假设我有一些不需要可逆的字符串,让我说我用SHA224
来对它进行哈希处理。
hello world
的哈希值为2f05477fc24bb4faefd86517156dafdecec45b8ad3cf2522a563582b
,其长度为56个字节。
如果我将每两个字符转换为其数字表示并从中产生一个字节怎么办?
在Python中我会做这样的事情:
shalist = list("2f05477fc24bb4faefd86517156dafdecec45b8ad3cf2522a563582b")
for first_byte,next_byte in zip(shalist[0::2],shalist[1::2]):
chr(ord(first_byte)+ord(next_byte))
结果将为\x98ek\x9d\x95\x96\x96\xc7\xcb\x9ckhf\x9a\xc7\xc9\xc8\x97\x97\x99\x97\xc9gd\x96im\x94
。 28个字节。有效地减少了输入。
现在,这样做是否存在更高的哈希冲突风险?
答案 0 :(得分:1)
简单的答案非常明显:是的,它增加了碰撞的几率,因为有2个缺失的位数。对于减少到28字节的56个字节,您可以获得碰撞增加2 ^(28 * 8)的机会。这仍然有可能在1:2 ^(28 * 8)处发生碰撞。
你对截断的使用仍然是完全合法的,取决于它是什么。例如,Git仅显示提交哈希中的前几个字节,并且对于大多数实际用途,短的一个工作正常。
A"完美"哈希应保留一定比例的"有效"比特,如果你截断它。例如,32位SHA256结果应具有相同的"强度"作为一个32位CRC,虽然可能有一些CRC的特殊属性使它更适合某些目的,而截断的SHA可能更好用于其他目的。
如果您使用此功能进行任何类型的安全保护,将很难证明您的系统,您可能更适合使用更短但完整的哈希值。
让我们缩小大小以理解它并使用2个字节的哈希而不是56个。原始哈希将有65536个可能的值,所以如果你的哈希值超过那么多,你肯定会发生冲突。对于1个字节的一半,在最多256个字符串哈希后,您将得到一个冲突,无论您是第一个还是第二个字节。所以你的碰撞几率是256(2 ^(1byte * 8bits))并且是1:256。
即使经过多年的密码分析,长期哈希仍被用来使暴力破坏它们真的不切实际。当MD5于1991年推出时,它被认为足够安全,可以用于证书签署,2008年被认为是#34;破坏"并不适合与安全相关的用途。可以开发各种密码分析技术来减少"有效的"哈希和加密算法的强度,所以有更多的备用比特(在一个强大的算法中),为了所有实际目的,应该保留更有效的比特来保持哈希的安全。