Python 3 使用密钥 sha512 签署消息

Python 3 sign a message with key sha512

我有下面一行代码:

return hmac.new(self.Secret.upper() , message , hashlib.sha512).digest().encode("base64").replace("\n","")

这在 Python2 中工作正常,但在 Python 中却不行 3. 我在 Python 3 中尝试后,我得到:

TypeError: key: expected bytes or bytearray, but got 'str'

来自 hmac.py。我当然尝试过使用 bytes()bytearray() 转换 self.Secretmessage,但这也没有用。

我也尝试过使用hashlib.sha512生成密钥,但我不是很清楚。我有一个秘密 API 密钥需要用于签署 POST 数据,唯一明确的方法是使用 hmac.new(),但是当我最终得到一些可以作为字符串传递的它看起来一点也不像它应该的那样,正如预期的那样我无法用它进行身份验证。

另一个尝试是:

sign = hashlib.sha512(message_to_sign)
sign.update(self.Secret.upper())

这还会生成一个字符串,看起来与 Python 2.7 中原始代码中的工作密钥完全不同。

我也尝试了很多其他变体,但是 none 中的任何变体都给我任何有用的东西。

这个在 python 3.4.2:

上对我有用
print((base64.b64encode(hmac.new(bytearray("SECRET".upper(), "ASCII") , bytearray("TEST","ASCII") , hashlib.sha512).digest())).decode("ASCII").replace("\n", ""))

...并计算出正确的 HMAC。

您可能想将 "ASCII" 更改为其他编码。

hmac 哈希适用于二进制密钥和数据。在 python2 中,str 是一个 8 位字符序列,可与二进制互换,因此一切正常。在 python3 中,str 是一个 unicode 字符序列,必须编码为二进制才能工作。这应该有效:

return hmac.new(bytes(self.Secret.upper().encode('ascii')) , bytes(message.encode('ascii') , hashlib.sha512).digest().encode("base64").replace("\n","")

注意我使用了 ascii 编码,但这只是一个猜测。您的 python2 字符串可能是您的本地代码页,您的消息可能已经是一个二进制 blob。您需要将使用的编码形式化,以便接收方知道如何验证签名。