I have been struggling with this for hours. I have the following production code (parsed out for simplicity) that runs just fine in Python 2.7:
import hashlib import hmac string1 = 'firststring' string2 = 'secondstring' digest = hmac.new(key=string1, msg=string2, digestmod=hashlib.sha256).digest() print('hmac_digest = ' + digest) # digest is a string
The output is a string like so:
hmac_digest = �!�Ni��I.u�����x�l*>a?. �
But when I run this with Python3.7, I get the following error:
Traceback (most recent call last): File "/home/xxxx/work/py23.py", line 7, in <module> digest = hmac.new(key=string1, msg=string2, digestmod=hashlib.sha256).digest() File "/usr/lib/python3.7/hmac.py", line 153, in new return HMAC(key, msg, digestmod) File "/usr/lib/python3.7/hmac.py", line 49, in __init__ raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__) TypeError: key: expected bytes or bytearray, but got 'str' Process finished with exit code 1
After a quite a bit of research I understood that hmac has changed in 3.4 and beyond. Therefore I redid my code to the following:
import hashlib import hmac import base64 string1 = 'firststring' string2 = 'secondstring' digest = hmac.new(key=string1.encode('utf-8'), msg=string2.encode('utf-8'), digestmod=hashlib.sha256).digest() digest = base64.encodebytes(digest).decode('utf-8') # need to convert to string print('hmac_digest = ' + digest)
But the output I get is completely different!
hmac_digest = 5CEZhgMDTmmFxkkudbGPxaLSytl4+gdsKj4PYT8uAJk=
How do I correctly port this code to python3.7 so I get the exact same output as 2.7?
Thanks in advance!
Advertisement
Answer
Thanks to Josh Lee for his answer in UnicodeDecodeError, invalid continuation byte
His suggestion about using ‘latin-1’ to decode the digest output solved the problem for me!
Here’s how my code looks in Python 3.7 now and gives me the exact same output as my code in Python 2.7:
import hashlib import hmac string1 = 'firststring'.encode('utf-8') # can use 'latin-1' string2 = 'secondstring'.encode('utf-8') # can use 'latin-1' digest = hmac.new(key=string1, msg=string2, digestmod=hashlib.sha256).digest() print('hmac_digest = ' + digest.decode('latin-1')) # Use only 'latin-1' to decode because 'utf-8' or 'ascii' will throw a UnicodeDecodeError