Hash 将每个SHA224 2字节减半到1字节以将哈希长度减半是否会带来更高的冲突风险?

Hash 将每个SHA224 2字节减半到1字节以将哈希长度减半是否会带来更高的冲突风险?,hash,hash-collision,sha2,Hash,Hash Collision,Sha2,假设我有不需要可逆的字符串,并使用SHA224对其进行散列 hello world的散列为2F05477FC24BB4FAEFD86517156DAFDEC45B8AD3CF2522A563582B,长度为56字节 如果我把每两个字符转换成它的数字表示,并从中提取一个字节,会怎么样 在Python中,我会这样做: shalist = list("2f05477fc24bb4faefd86517156dafdecec45b8ad3cf2522a563582b") for first_byte,ne

假设我有不需要可逆的字符串,并使用
SHA224
对其进行散列

hello world
的散列为
2F05477FC24BB4FAEFD86517156DAFDEC45B8AD3CF2522A563582B
,长度为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\x9gd\x96im\x94
。28字节。有效地将投入减半


现在,这样做是否会有更高的哈希冲突风险?

简单的答案很明显:是的,它会增加冲突的几率,增加的次数与丢失的比特数相同。如果将56字节减半为28字节,则冲突几率增加2^(28*8)。这仍然使碰撞的几率保持在1:2^(28*8)

您对截断的使用仍然是完全合法的,这取决于它是什么。例如,Git只显示提交散列的前几个字节,而对于大多数实际用途,短的字节可以正常工作

如果截断“完美”散列,它应该保留一定比例的“有效”位。例如,SHA256结果的32位应具有与32位CRC相同的“强度”,尽管CRC可能具有一些特殊属性,使其更适合某些用途,而截断的SHA可能更适合其他用途

如果你正在用这个做任何类型的安全性测试,那么很难证明你的系统,你最好使用一个更短但完整的散列

让我们缩小大小以理解它,并使用2字节哈希而不是56字节。原始散列将有65536个可能的值,因此如果散列的字符串数超过那么多,则肯定会发生冲突。将其减半到1个字节,在对最多256个字符串进行哈希运算后,无论使用第一个字节还是第二个字节,都会发生冲突。因此,碰撞的几率要大256(2^(1byte*8bits)),并且是1:256


长散列被用来使暴力强迫它们变得真正不切实际,即使经过多年的密码分析。当MD5于1991年引入时,它被认为足够安全,可以用于证书签名,而在2008年,它被认为是“坏的”,不适合与安全相关的使用。可以开发各种密码分析技术来降低散列和加密算法的“有效”强度,因此(在其他强算法中)有更多的空闲位更有效的位应该保留下来,以确保哈希在所有实际用途中都是安全的。

我非常确定,每转换两个字符,然后从中生成一个字节是一个内射函数。如果是这样的话,它不应该有更高的哈希冲突风险。