简体   繁体   English

Python 3使用密钥sha512对消息进行签名

[英]Python 3 sign a message with key sha512

I have the following line of code: 我有以下代码行:

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

This works fine in Python2, but not in Python 3. As soon as I try in Python 3 I get: 在Python2中可以正常工作,但在Python 3中则不能。在Python 3中尝试后,我会得到:

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

from hmac.py . 来自hmac.py I've of course tried converting self.Secret and message using bytes() and bytearray() , but that hasn't worked either. 我当然已经尝试使用bytes()bytearray()转换self.Secretmessage ,但是那也不起作用。

I've also tried using hashlib.sha512 to generate the key, but that's not very clear to me. 我也尝试过使用hashlib.sha512生成密钥,但这对我来说还不是很清楚。 I have a secret API key that needs to be used to sign the POST data and the only clear way to do this is using hmac.new() , but when I finally do get something that can be passed as a string it looks nothing like it should, and as expected I can't authenticate with it. 我有一个秘密的API密钥,需要用于签名POST数据,唯一明确的方法是使用hmac.new() ,但是当我最终得到可以作为字符串传递的内容时,它看起来就不像应该,而且正如我所料,我无法对其进行身份验证。

Another attempt was: 另一个尝试是:

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

This also produces a string that looks nothing like the working key that comes from the original code in Python 2.7. 这还会产生一个看起来与Python 2.7原始代码中的工作键完全不同的字符串。

I've tried so many other variations as well, but none of them give me anything that works. 我也尝试了许多其他变体,但没有一个能给我任何有用的东西。

This one works for me on python 3.4.2: 这对我适用于python 3.4.2:

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

...and calculates a correct HMAC. ...并计算出正确的HMAC。

You might want to change "ASCII" to some other encoding. 您可能需要将"ASCII"更改为其他某种编码。

hmac hashing works with binary keys and data. hmac哈希处理二进制密钥和数据。 In python2, str is a sequence of 8 bit characters which is interchangable with binary so everything works. 在python2中, str是8位字符的序列,可以与二进制互换,因此一切正常。 In python3, str is a sequence of unicode characters and must be encoded to binary to work. 在python3中, str是一串unicode字符,必须将其编码为二进制才能工作。 This should work: 这应该工作:

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

Notice I used ascii encoding but that's just a guess. 注意,我使用了ascii编码,但这只是一个猜测。 Your python2 strings may be your local code page and your message may be a binary blob already. 您的python2字符串可能是您的本地代码页,并且您的消息可能已经是二进制blob。 You'll need to formalize what encoding you use so that receivers know how to verify the signature. 您需要形式化使用哪种编码,以便接收者知道如何验证签名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM