我有以下代码行:
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
。我当然尝试使用self.Secret
和message
转换bytes()
和bytearray()
,但这也没有效果。
我也尝试使用hashlib.sha512
来生成密钥,但这对我来说并不是很清楚。我有一个秘密的API密钥需要用于签署POST数据,唯一明确的方法是使用hmac.new()
,但是当我最终得到一些可以作为字符串传递的东西时它看起来没什么它应该,并且如我所料,我无法通过它进行身份验证。
另一种尝试是:
sign = hashlib.sha512(message_to_sign)
sign.update(self.Secret.upper())
这也会产生一个字符串,它看起来与Python 2.7中原始代码的工作密钥完全不同。
我也尝试了很多其他的变体,但是没有一个能给我任何有用的东西。
答案 0 :(得分:2)
这个适用于我的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"
更改为其他编码。
答案 1 :(得分:2)
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。您需要形式化您使用的编码,以便接收方知道如何验证签名。