I want to implement the hmac algorithm with SHA-1 by the definition from RFC 2104. The code is running but the results aren't the same as the test-vectors from RFC. I'm not sure if I'm loading the values correctly(String to Hex, or String to Bytes?).
As template I've used the pseudo-code from wikipedia
I'm not sure about the terms 'blocksize' and 'output size'. In the code from wikipedia the outputsize is one of the input values but never used.
This is my code so far: First I'm setting up a hash-function, then I'm converting my input-strings (key and message) into hex values. Next step is to to look if key hast go get hashed or filled with zeros. Next I'm xor-ing the single chars from the key with those values (I don't know where they come from, but they're in every example without any comment). Last but not least I'm combining an inner string(I_key_pad + message) and hash it which results in an outer strings that im combining with the outer pad and hash it again.
import hashlib
from functools import reduce
def hmac(key, message, hashfunc):
hasher = hashlib.sha1
blocksize = 40
message = toHex(message) #is this right?
key = toHex(key)
#alternative: loading values as bytes
#message = bytes(message, 'utf-8')
#key = bytes(key, 'utf-8')
if len(key) > blocksize:
key = hasher(key)
else:
#key = key.ljust(blocksize, '0') #filling from right to left
#key = key.ljust(blocksize, b'\0') #same as above but for bytes
key = pad(key, blocksize) #filling from left to right
val1 = 0x5c
val2 = 0x36
i = 0
o_key_pad = ""
i_key_pad = ""
while i < blocksize:
o_key_pad += str(ord(key[i]) ^ val1)
i_key_pad += str(ord(key[i]) ^ val2)
i += 1
tmp_string = str(i_key_pad) + str(message)
tmp_string = tmp_string.encode()
inner_hash = hasher(tmp_string).hexdigest()
fullstring = str(o_key_pad) + inner_hash
fullstring = fullstring.encode()
fullstring = hasher(fullstring).hexdigest()
print(fullstring)
def pad(key, blocksize):
key = str(key)
while len(key) < blocksize:
key = '0' + key
key = key
return key
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0' + hv
lst.append(hv)
return reduce(lambda x, y: x + y, lst)
def main():
while (1):
key = input("key = ")
message = input("message = ")
hash = input("hash (0: SHA-256, 1: SHA-1) = ")
hmac(key, message, hash)
if __name__ == "__main__":
main()