【发布时间】:2025-12-27 16:25:15
【问题描述】:
我想根据 RFC 2104 的定义使用 SHA-1 实现 hmac 算法。代码正在运行,但结果与 test-vectors from RFC 不同。我不确定我是否正确加载了值(字符串到十六进制,还是字符串到字节?)。
作为模板,我使用了来自wikipedia的伪代码
我不确定“块大小”和“输出大小”这两个术语。在来自*的代码中,输出大小是输入值之一,但从未使用过。
到目前为止,这是我的代码: 首先,我设置了一个哈希函数,然后我将输入字符串(键和消息)转换为十六进制值。下一步是查看密钥是否被散列或填充为零。接下来,我用这些值对键中的单个字符进行异或运算(我不知道它们来自哪里,但它们在每个示例中都没有任何评论)。最后但并非最不重要的一点是,我正在组合一个内部字符串(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'\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()
【问题讨论】:
-
您能否提供一个我们可以运行的完整、可验证的示例?期望人们自己开始工作并从头开始调试的代码很多。
-
嘿@MisterMiyagi 感谢您的评论。我添加了一些东西。这都是关于 hmac() 函数的。我的主要问题不是我的代码不起作用。这更像是一种实践的理论。
-
我的意思是“为预期输入和预期/实际输出提供样本”,这样人们就不必通读整个 RFC。
-
我不明白您为什么要将数据转换为十六进制编码值,这在我看来是错误的。始终以字节为单位。这是python3,对吗?
-
@JamesKPolk 是的,这是 python3。我想我这样做是因为绝望。在我完成了代码的基础后,我尝试了大约 8 个小时来得到正确的结果