在考虑到MD5算法的破解和安全问题等因素之后,对文件进行MD5哈希处理仍然被认为是足够好的唯一标识方法吗?这里我的主要关注点不是安全性,而是对每个文件进行唯一性标识。
有什么想法吗?
在考虑到MD5算法的破解和安全问题等因素之后,对文件进行MD5哈希处理仍然被认为是足够好的唯一标识方法吗?这里我的主要关注点不是安全性,而是对每个文件进行唯一性标识。
有什么想法吗?
是的。从安全角度来看,MD5已经完全被攻破了,但是发生偶然冲突的概率仍然非常小。只要确保文件不是由您不信任且可能有恶意意图的人创建的即可。
为了实际应用而创建的哈希值可能足够随机,但从理论上讲,由于鸽巢原理(Pigeonhole principle),总会存在碰撞的概率。虽然具有不同哈希值意味着文件不同,但相同哈希值并不一定意味着文件相同。
因此,使用哈希函数来实现这个目的 - 无论是否涉及到安全问题 - 都应该始终是检查的第一步,特别是如果已知哈希算法容易产生碰撞时。要可靠地确定两个具有相同哈希值的文件是否不同,您需要逐字节比较这些文件。
如果你没有对手,MD5足够好。然而,有人可以(刻意)创建两个不同的文件,它们的哈希值相同(这称为碰撞),这可能是一个问题或不是问题,具体取决于您的情况。
由于知道已知的MD5弱点是否适用于给定的上下文是一个微妙的问题,因此建议不要使用MD5。使用防碰撞哈希函数(SHA-256或SHA-512)是安全的选择。此外,使用MD5会导致不良的公共关系(如果你使用MD5,请准备好为自己辩护;而没有人会质疑你使用SHA-256)。
MD5可以产生碰撞。理论上,虽然可能性很小,但一百万个文件连续产生相同的哈希是有可能的。在存储值之前,请检查md5碰撞,不要冒险。
我个人喜欢创建随机字符串的md5,这样可以减少对大文件进行哈希的开销。当发现碰撞时,我会迭代并重新添加循环计数器进行哈希。
您可以阅读关于鸽笼原理的内容。
我个人认为人们在需要唯一标识符时过度使用其他对象的原始校验和(选择您的方法)作为唯一标识符。将对象指纹化用于此目的并非旨在,可能需要更多的思考才能使用UUID或类似完整性机制。
当对短字符串(小于几千字节?)或文件进行哈希时,可以创建两个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已经被破解,您可以使用SHA1代替(大多数语言都实现了)
我喜欢将MD5视为在存储大量文件数据时的概率指示器。
如果散列值相等,则我知道我必须逐字节比较文件,但由于错误原因,这可能只发生几次,否则(散列值不相等),我可以确定我们正在谈论两个不同的文件。