MD5仍然足够用于唯一标识文件吗?

159

在考虑到MD5算法的破解和安全问题等因素之后,对文件进行MD5哈希处理仍然被认为是足够好的唯一标识方法吗?这里我的主要关注点不是安全性,而是对每个文件进行唯一性标识。

有什么想法吗?


2
我目前正在我的一个应用程序中使用它,据我所知,它足以唯一地标识文件。 - Not Available
2
您可能会发现这个问题:https://dev59.com/W3RA5IYBdhLWcg3wsgFP 有用。 - sharptooth
相关链接:https://dev59.com/UmUp5IYBdhLWcg3w5Kk6 - NeDark
@Marcin:除非你拥有千万亿个文件,否则你不会遇到生日悖论。你没有。 - Keith Thompson
如果你想查找重复照片,最好使用专门用于此目的的软件,而不是比较文件哈希值。看起来完全相同或非常相似的照片可能具有不同的文件哈希值,这取决于照片元数据(如分辨率、EXIF 数据等)的差异。 - ADTC
显示剩余2条评论
9个回答

97

是的。从安全角度来看,MD5已经完全被攻破了,但是发生偶然冲突的概率仍然非常小。只要确保文件不是由您不信任且可能有恶意意图的人创建的即可。


2
对于您的第一个问题,请参见这里。恐怕我不理解其他问题。 - Marcelo Cantos
9
@0xA3: 你和我都不知道OP所指的文件是什么,或者泄露会造成多大的损害。这些文件可能是他们孩子的婴儿照片合集,我们并不清楚。我的目标是提供事实;其他人如何处理这些信息是他们的事情。同时请考虑布鲁斯·施奈尔(Bruce Schneier)的建议:将密码写下来;并非所有东西都需要存储在强盗堡垒(Fort Knox)。有些东西放在花盆下也可以安全保存。 - Marcelo Cantos
3
@Marcelo Cantos,我认为这里缺乏的是对“安全”一词的区分或分解。显然人们假定在任何使用校验和工作时都需要“安全”,但Marcelo可能指的术语是“在实验室中”。 - hpavc
5
我强烈不同意。不同的哈希值表示文件是不同的。但如果哈希值相同,你不能说“它们很可能是相同的”,你只能逐字节进行比较。哈希值比整个文件的不同值数量小好几个数量级,因此对于每个哈希值,可能会有许多可能的碰撞。只有在复制已知文件(具有已知哈希)的情况下,完全相同的哈希值“可能意味着”第二份被正确复制(即使在这种情况下,也不是100%确定,但高度可能)。 - Olivier Dulac
3
好的,我的数学不太好。GUID具有大约122位熵,因此在十亿个文件中发生冲突的概率约为2^(2*30 - 122) = 2^-62。虽然这比我最初的计算要高得多,但仍然微不足道,大约是四千万亿分之一。 - Marcelo Cantos
显示剩余13条评论

35

为了实际应用而创建的哈希值可能足够随机,但从理论上讲,由于鸽巢原理(Pigeonhole principle),总会存在碰撞的概率。虽然具有不同哈希值意味着文件不同,但相同哈希值并不一定意味着文件相同。

因此,使用哈希函数来实现这个目的 - 无论是否涉及到安全问题 - 都应该始终是检查的第一步,特别是如果已知哈希算法容易产生碰撞时。要可靠地确定两个具有相同哈希值的文件是否不同,您需要逐字节比较这些文件。


16
@Ranhiru。不行。哈希算法会给你一个“摘要”值,对于MD5来说只有16个字节长。如果要保证文件相同,你需要逐字节检查。无论你选择什么哈希算法,这都是真的,总有可能发生冲突。 - PaulG
6
重新阅读这个答案,我认为它是这里最全面的答案。哈希可以用作第一步,它可以让你以99.99^e%的确定性知道文件是相同的,但如果你想要绝对100%的确定性,那么你需要进行逐字节检查。无论你使用MD5、SHA还是任何其他算法都是如此。 - PaulG
10
这个答案是错误的。防止篡改和验证唯一性是同一件事情。而且,虽然哈希不能保证唯一性,实际比较也无法保证。实际上,哈希偶然碰撞的概率比由正常太阳伽玛射线引起的CPU故障导致比较失败的概率要低得多。还要记住,文件的唯一来源通常位于另一端的Web服务器中,您唯一可用于比较的独立信息是哈希值。 - Marcelo Cantos
8
@Marcelo。从逻辑上讲,偶然的碰撞比偶然的位翻转(在逐字节比较时)更不可能,这是站不住脚的。在构建哈希时仍有相同的位翻转几率(而且可以说更高,因为需要更多处理时间)。@Thomas最初提出这一点是为了表明没有保证的方法来确定唯一性,尽管位翻转的影响非常有争议。最悲观的估计是每GB/小时1个位翻转,而ECC RAM甚至可以消除这个问题。 - PaulG
3
“哈希值意外冲突的可能性实际上比由正常太阳伽马射线引起的CPU故障导致比较失败的概率要低” [需要引用来源] - endolith
显示剩余17条评论

20

如果你没有对手,MD5足够好。然而,有人可以(刻意)创建两个不同的文件,它们的哈希值相同(这称为碰撞),这可能是一个问题或不是问题,具体取决于您的情况。

由于知道已知的MD5弱点是否适用于给定的上下文是一个微妙的问题,因此建议不要使用MD5。使用防碰撞哈希函数(SHA-256或SHA-512)是安全的选择。此外,使用MD5会导致不良的公共关系(如果你使用MD5,请准备好为自己辩护;而没有人会质疑你使用SHA-256)。


2
如果读者对哈希不太熟悉,这个答案可能会有点误导。SHA并没有什么神奇的地方可以防止哈希碰撞,它们只是更抵抗哈希碰撞攻击。如果您想要超过99.999^e%的确定性来判断文件是否相同,您仍需要进行逐字节的检查。 - PaulG
7
实际上,字节比较可能会因宇宙射线反转一位而失败(例如将“return 0;”转换为“return 1;”)。虽然这种情况极不可能发生,但与SHA-256的碰撞风险甚至更小。从数学上讲,您无法确定哈希到同一值的两个文件是否相同,但是只要使用计算机进行比较,比较文件本身也无法确保它们是否相同。我的意思是,超出99.999....9%的确定性是毫无意义的,而SHA-256已经提供了更多的确定性。 - Thomas Pornin
2
什么?你不使用ECC内存?;)。好评论,非常有趣的想法。 - PaulG
1
不要忘记穿上锡箔帽!更严肃地说,你是如何知道这些关于碰撞的小知识,并且你是否以某种方式进行了验证? - James P.
@ThomasPornin 宇宙射线的位翻转也会影响MD5方法,所以它仍然更糟。 - endolith
1
各位,我认为你们在这里陷入了数学/哲学的可能性中。从实用主义的角度来看,MD5/SHA-256和其他众所周知的哈希算法足够强大,可以用于确定文件等效性。如果您想要更加确保 (也就是偏执), 可以在文件配对上运行两个不同的哈希算法。我会假设给定两个文件,我会检查它们的大小是否相等,如果相等,然后才会继续计算哈希值。 - in70x

9

MD5可以产生碰撞。理论上,虽然可能性很小,但一百万个文件连续产生相同的哈希是有可能的。在存储值之前,请检查md5碰撞,不要冒险。

我个人喜欢创建随机字符串的md5,这样可以减少对大文件进行哈希的开销。当发现碰撞时,我会迭代并重新添加循环计数器进行哈希。

您可以阅读关于鸽笼原理的内容。


6
我不建议使用MD5。如果应用程序在多用户系统上工作,可能会有用户拥有两个具有相同md5哈希的文件(他可能是工程师并且玩弄这样的文件,或者只是出于好奇心 - 它们可以从http://www2.mat.dtu.dk/people/S.Thomsen/wangmd5/samples.html轻松下载,我在撰写此答案时下载了两个样本)。另一件事是,某些应用程序可能为任何原因存储此类重复项(我不确定是否有任何此类应用程序,但可能性存在)。
如果您正在唯一标识由程序生成的文件,则我认为可以使用MD5。否则,我建议使用其他尚未知道碰撞的哈希函数。

2

我个人认为人们在需要唯一标识符时过度使用其他对象的原始校验和(选择您的方法)作为唯一标识符。将对象指纹化用于此目的并非旨在,可能需要更多的思考才能使用UUID或类似完整性机制。


1

当对短字符串(小于几千字节?)或文件进行哈希时,可以创建两个md5哈希密钥,一个用于实际字符串,另一个用于反转字符串并连接短不对称字符串。例如:md5(reverse(string ||'1010'))。添加额外的字符串可确保即使由一系列相同位组成的文件也会生成两个不同的密钥。请注意,即使在此方案下,两个哈希密钥对于非相同字符串有理论上的相等机会,但概率似乎极小-大约是单个md5碰撞概率的平方,而且随着文件数量的增加,节省的时间可能会很多。还可以考虑更复杂的方案来创建第二个字符串,但我不确定这些方案是否会显著提高胜算。

要检查冲突,可以运行此测试以检查所有位向量中md5哈希密钥的唯一性:

select md5 ( bit_vector ), count(*), bit_and ( bit_vector) from db with bit_vector
group by md5( bit_vector ), bit_vector having bit_and ( bit_vector ) <> bit_vector


聪明的想法。如果“攻击者”制作了一个具有相同md5哈希值的伪造文件,除非他知道你的“盐”,否则这将没有任何帮助,并且反转内容会创建不同的哈希值。使用2个md5密钥可以大大降低几率。如果只是为了防止“攻击”,在本地计算之前使用盐就足够了。 - Wolf5

0

MD5已经被破解,您可以使用SHA1代替(大多数语言都实现了)


这是一个非常好的答案。从2018年5月开始,在欧洲的法律和会计使用情况中,MD5是不可接受的。 - Bert Sinnema
@BertSinnema,你能告诉我哪里可以找到定义可接受的哈希函数的源代码吗?谢谢。 - berezovskyi
1
@GregSchmit 可能是因为 OP 并不关心密码强度本身。我理解这个问题是“我已经在非安全环境中使用了 MD5,我需要花时间更新代码吗?”这种情况。在这种情况下,答案很可能是错误的,因为 SHA1 也已经被攻破了。 - berezovskyi

0

我喜欢将MD5视为在存储大量文件数据时的概率指示器。

如果散列值相等,则我知道我必须逐字节比较文件,但由于错误原因,这可能只发生几次,否则(散列值不相等),我可以确定我们正在谈论两个不同的文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接