kaaleppi3
kaaleppi3

Reputation: 95

Implementing SHA1-HMAC with Python

I am implementing SHA1-HMAC generation for python (v 3.7) to be able to create HMAC code.

I have used an online generator to create SHA1-HMAC with the following data:

I am getting this result:

b14e92eb17f6b78ec5a205ee0e1ab220fb7f86d7

However when I try to do this same with Python I am getting different results which are wrong.

import hashlib
import hmac
import base64

def make_digest(message, key):
    key = bytes(key, 'UTF-8')
    message = bytes(message, 'UTF-8')

    digester = hmac.new(key, message, hashlib.sha1)
    signature1 = digester.digest()

    signature2 = base64.urlsafe_b64encode(signature1)    
    return str(signature2, 'UTF-8')


result = make_digest('123', 'secret')
print(result)

This code gives result:

sU6S6xf2t47FogXuDhqyIPt_htc=

What could be wrong with this code?

Upvotes: 6

Views: 4839

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121844

You should not use Base64 here. The site you link to gives you the hex values of the digest bytes. Use the HMAC.hexdigest() method to get the same value in hex in Python:

>>> key = b'secret'
>>> message = b'123'
>>> digester = hmac.new(key, message, hashlib.sha1)
>>> digester.hexdigest()
'b14e92eb17f6b78ec5a205ee0e1ab220fb7f86d7'

put differently, your code outputs the correct value, but as Base64-encoded data:

>>> digester.digest()
b'\xb1N\x92\xeb\x17\xf6\xb7\x8e\xc5\xa2\x05\xee\x0e\x1a\xb2 \xfb\x7f\x86\xd7'
>>> base64.urlsafe_b64encode(digester.digest())
b'sU6S6xf2t47FogXuDhqyIPt_htc='

and the value you generated online contains the exact same bytes as the hex digest, so we can generate the same base64 output for that:

>>> bytes.fromhex('b14e92eb17f6b78ec5a205ee0e1ab220fb7f86d7')
b'\xb1N\x92\xeb\x17\xf6\xb7\x8e\xc5\xa2\x05\xee\x0e\x1a\xb2 \xfb\x7f\x86\xd7'
>>> base64.urlsafe_b64encode(bytes.fromhex('b14e92eb17f6b78ec5a205ee0e1ab220fb7f86d7'))
b'sU6S6xf2t47FogXuDhqyIPt_htc='

Upvotes: 9

Related Questions