我想通过RFC 2104的定义实现使用SHA-1的HMAC算法。该代码正在运行,但结果与RFC的测试 - 向量不同。我不确定我是否正确加载值(字符串到十六进制或字符串到字节?(。
作为模板,我使用了Wikipedia的伪代码
我不确定术语"阻止"one_answers"输出大小"。在Wikipedia的代码中,输出尺寸是输入值之一,但从未使用过。
这是我到目前为止的代码:首先,我要设置一个功能,然后将输入串(密钥和消息(转换为HEX值。下一步是查看钥匙是否要进行哈希或充满零。接下来,我将用这些值从钥匙中获得单个字符(我不知道它们来自何处,但是在每个示例中,没有任何评论(。最后但并非最不重要的一点是,我将内部字符串(I_KEY_PAD 消息(组合在一起,并将其放大,从而导致外部字符串与外部垫子结合并再次进行哈希。
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' ') #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()
我不了解您的代码中的所有步骤,但是这是一个仅使用hashlib.sha1
的HMAC-SHA1的简短示例,带有辅助功能xor
。
import hashlib
def xor(x, y):
return bytes(x[i] ^ y[i] for i in range(min(len(x), len(y))))
def hmac_sha1(key_K, data):
if len(key_K) > 64:
raise ValueError('The key must be <= 64 bytes in length')
padded_K = key_K + b'x00' * (64 - len(key_K))
ipad = b'x36' * 64
opad = b'x5c' * 64
h_inner = hashlib.sha1(xor(padded_K, ipad))
h_inner.update(data)
h_outer = hashlib.sha1(xor(padded_K, opad))
h_outer.update(h_inner.digest())
return h_outer.digest()
def do_tests():
# test 1
k = b'x0b' * 20
data = b"Hi There"
result = hmac_sha1(k, data)
print(result.hex())
# add tests as desired