对于小字符串哈希,我应该使用 MD5 等已弃用的算法还是 SHA256 等算法的前缀?



我有 16 个字节来保存字符串哈希。我知道当您将任意长度的字符串减少到固定长度的字节序列时,冲突是生活中的事实,但我想尽可能避免它们。我最好使用输出为 16 字节的 MD5 等已弃用的算法,还是使用尚未损坏的算法(如 SHA-256)的前 16 个字节?

鉴于NIST将SHA-224定义为截断的SHA-256,这是官方的"批准印章",因为您将要回答"截断SHA-256以适应尺寸要求是个好主意吗?

由于 MD5 被彻底拆除,并且很快就会加入 MD4 的"甚至不用于内部测试"的架子上,答案非常明确 - 使用截断的 SHA-256。

话虽如此,当你减少它的那一刻 - 碰撞的数量自然会增加。SHA-256 在统计上传播良好,因此缩短不应该比只有 128 位的不可避免地增加的冲突更多(好吧,更多一点,因为没有哈希是完美的)。缩短甚至会带来一个好处,即增加已经稳固的SHA-256对长度延伸攻击的抵抗力。

我知道业内很多系统使用减半的 SHA-512 来增加对 LAE 的抵抗力(嗯,目前是理论上的)而不是 SHA-256 - 额外的好处是在计算 SHA-512 与 SHA-256 时 64 位系统的性能提升。

我遇到的最常见的截断形式是将前半部分与后半部分进行异或运算。我不确定它是否提供了任何额外的好处,但是当人们看到"截断器"的"无法识别"输出时,他们会感到更自在,所以他们只是使用它。

更新

根据deceze的建议 - 当哈希被限定为"甚至不用于内部测试"时,这意味着它的设计工作做得不好,应该不惜一切代价避免该特定应用程序,但不一定用于其他应用程序。

MD4和 MD5 都可以用作非加密设置中的固体散列算法,我已经看到系统专门为此重新利用 MD4 - 它非常快,具有可靠的传播,如果你对冲突不太挑剔(假设你正在构建一个备份程序,需要知道自上次备份以来哪些文件发生了变化),它可以与一些为这些特定目的设计的非加密哈希正面交锋。

但是,通常情况下,最好使用正确的工具来完成工作。非加密哈希首先是为了速度而设计的,也是为了传播和低碰撞率而设计的,其中一些甚至超过了加密哈希,它们的配置文件只有或多或少可预测的缺点。

如果你需要一个非加密哈希,而不是求助于破碎的加密哈希,我建议你看看一些用于非加密目的的整体更好的哈希,如FNV-1/FNV-1a,Murmur甚至普通的CRC32(有点慢,但比大多数加密哈希更快)。SE上的速度,传播和碰撞有一个非常好的比较,所以一定要检查一下。

最新更新