Skip to content
Advertisement

Port hmac.new().digest() module from Python 2.7 to 3.7

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
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement