在hmac.py的顶部是行:
trans_5C = "".join ([chr (x ^ 0x5C) for x in xrange(256)])
trans_36 = "".join ([chr (x ^ 0x36) for x in xrange(256)])
但是HMAC RFC(以及我能找到的所有其他源)声明内部和外部填充应该是重复的字节0x5C和0x36,而不是与一系列数字进行异或。也就是说,我希望看到:
trans_5C = chr(0x5C) * 256
trans_36 = chr(0x36) * 256
我错过了什么?
答案 0 :(得分:3)
这不是不正确的。该代码应用了一种非遗忘的优化。
代码:
trans_5C = "".join ([chr (x ^ 0x5C) for x in xrange(256)])
trans_36 = "".join ([chr (x ^ 0x36) for x in xrange(256)])
实际上计算翻译字符串,后者用于执行内部和外部填充的XOR操作。 HMAC
类__init__
中的代码后者通过translate函数和预先计算的字符串间接执行XOR操作:
self.outer.update(key.translate(trans_5C))
self.inner.update(key.translate(trans_36))
然后让我们看看key.translate(trans_5C)
做了什么:
str.translate(table[, deletechars])
返回字符串的副本,其中删除了可选参数
deletechars
中出现的所有字符,其余字符已通过给定的转换表进行映射,转换表必须是长度为256的字符串。
可以证明key.translate(trans_5C)
是以下的优化版本:
''.join(chr(ord(k) ^ 0x5C) for k in key)
由此:
>>> trans_5C = "".join ([chr (x ^ 0x5C) for x in xrange(256)])
>>> key = '0123456789'
>>> key.translate(trans_5C)
'lmnohijkde'
>>> ''.join(chr(ord(k) ^ 0x5C) for k in key)
'lmnohijkde'
这两个表达式的值是相同的。如果0x5C
替换为0x36
,则同样适用。