1

假设我有不需要可逆的字符串,假设我用SHA224它来散列它。

is的哈希值,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 字节。有效地将输入减半。

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

4

1 回答 1

1

简单的答案非常明显:是的,它增加了 2 的幂与丢失的位一样多的机会。对于减半为 28 字节的 56 字节,您的冲突机会增加了 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 年,它被认为是“损坏的”,不适合与安全相关的用途。可以开发各种密码分析技术来降低散列和加密算法的“有效”强度,因此备用位越多(在其他强大的算法中),应保留的有效位越多,以确保散列在所有实际用途中的安全。

于 2015-04-24T22:53:12.737 回答