【发布时间】:2020-10-19 08:22:53
【问题描述】:
我想用 JavaScript 重新实现某个用 Python 编写的 API 客户端。我无法复制 HMAC SHA256 签名功能。对于某些键,输出是相同的,但对于某些键则不同。当密钥在解码其 Base64 表示后由可打印字符组成时,输出似乎是相同的。
Python
#!/usr/bin/env python3
import base64
import hashlib
import hmac
def sign_string(key_b64, to_sign):
key = base64.b64decode(key_b64)
signed_hmac_sha256 = hmac.HMAC(key, to_sign.encode(), hashlib.sha256)
digest = signed_hmac_sha256.digest()
return base64.b64encode(digest).decode()
print(sign_string('VGhpcyBpcyBhIHByaW50YWJsZSBzdHJpbmcuCg==', "my message"))
print(sign_string('dGhlIHdpbmQgb2YgTXQuIEZ1amkK', "my message"))
print(sign_string('pkmNNJw3alrpIBi5t5Pxuym00M211oN86IhLZVT8', "my message"))
JavaScript
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac-sha256.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/enc-base64.min.js"></script>
<script>
function sign_string(key_b64, to_sign) {
key = atob(key_b64)
var hash = CryptoJS.HmacSHA256(to_sign, key);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
document.write(hashInBase64 + '<br>');
}
sign_string('VGhpcyBpcyBhIHByaW50YWJsZSBzdHJpbmcuCg==', "my message")
sign_string('dGhlIHdpbmQgb2YgTXQuIEZ1amkK', "my message")
sign_string('pkmNNJw3alrpIBi5t5Pxuym00M211oN86IhLZVT8', "my message")
</script>
输出
Python
TdhfUQfym16HyWQ8wxQeNVvJKr/tp5rLKHYQSpURLpw=
pQ5NzK3KIWjqc75AXBvWgLK8X0kZvjRHXrLAdxIN+Bk=
8srAvMucCd91CWI7DeCFjxJrEYllaaH63wmVlMk0W+I=
JavaScript
TdhfUQfym16HyWQ8wxQeNVvJKr/tp5rLKHYQSpURLpw=
pQ5NzK3KIWjqc75AXBvWgLK8X0kZvjRHXrLAdxIN+Bk=
31QxOpifnpFUpx/sn336ZmmjkYbLlNrs8NP9om6nPeY=
如您所见,前两个相同,而最后一个不同。
如何将 JavaScript 代码更改为与 python 代码相同的行为?
【问题讨论】:
-
在第三个 sign_string 调用中提供的键在两个示例中是不同的。
-
你在第三个传递不同的值
-
好吧,这很尴尬。最后一分钟复制粘贴错误。我现在将示例更改为具有相同的输入,但输出仍然不同。
-
您可能想研究使用 SubtleCrypto 接口,而不是依赖额外的库。 developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/sign
标签: javascript python hmac sha cryptojs