Hash算法的「碰撞」 Posted 2021-04-12 澳链财经
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hash算法的「碰撞」相关的知识,希望对你有一定的参考价值。
我们尝试的散列算法得到的值一定是一个不大于8的自然数,因此,如果我们随便拿9个数去计算,肯定至少会得到两个相同的值,我们把这种情况就叫做
散列算法的「碰撞」(Collision)
。
这很容易理解,因为作为一种可用的散列算法,其位数一定是有限的,也就是说它能记录的文件是有限的——而文件数量是无限的,两个文件指纹发生碰撞的概率永远不会是零。
但这并不意味着散列算法就不能用了,因为凡事都要考虑代价,买光所有彩票去中一次头奖是毫无意义的。
现代散列算法所存在的理由就是,它的不可逆性能在较大概率上得到实现,也就是说,发现碰撞的概率很小,这种碰撞能被利用的概率更小。
随意找到一组碰撞是有可能的,只要穷举就可以。
散列算法得到的指纹位数是有限的,比如MD5算法指纹字长为128位,意味着只要我们穷举2^128次,就肯定能得到一组碰撞——当然,这个时间代价是难以想象的,而更重要的是,仅仅找到一组碰撞并没有什么实际意义。
更有意义的是,如果我们已经有了一组指纹,能否找到一个原始文件,让它的散列计算结果等于这组指纹。
如果这一点被实现,我们就可以很容易地篡改和伪造网络证书、密码等关键信息。
你也许已经听过MD5已经被破解的新闻——但事实上,即便是MD5这种已经过时的散列算法,也很难实现逆向运算。
我们现在更多的还是依赖于海量字典来进行尝试,也就是通过已经知道的大量的文件——指纹对应关系,搜索某个指纹所对应的文件是否在数据库里存在。
5.1 MD5的实际碰撞案例
下面让我们来看看一个真实的碰撞案例。
我们之所以说MD5过时,是因为它在某些时候已经很难表现出散列算法的某些优势——比如在应对文件的微小修改时,散列算法得到的指纹结果应当有显著的不同,而下面的程序说明了MD5并不能实现这一点。
a = bytearray.fromhex("0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef" )
b = bytearray.fromhex("0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef" )
print(hashlib.md5(a).hexdigest())
print(hashlib.md5(b).hexdigest())
cee9a457e790cf20d4bdaa6d69f01e41
cee9a457e790cf20d4bdaa6d69f01e41
而诸如此类的碰撞案例还有很多,上面只是原始文件相对较小的一个例子。
事实上现在我们用智能手机只要数秒就能找到MD5的一个碰撞案例,因此,MD5在数年前就已经不被推荐作为应用中的散列算法方案,取代它的是SHA家族算法,也就是安全散列算法(Secure Hash Algorithm,缩写为SHA)。
5.2 SHA家族算法以及SHA1碰撞
安全散列算法与MD5算法本质上的算法是类似的,但安全性要领先很多——这种领先型更多的表现在碰撞攻击的时间开销更大,当然相对应的计算时间也会慢一点。
SHA家族算法的种类很多,有SHA0、SHA1、SHA256、SHA384等等,它们的计算方式和计算速度都有差别。
其中SHA1是现在用途最广泛的一种算法。
包括GitHub在内的众多版本控制工具以及各种云同步服务都是用SHA1来区别文件,很多安全证书或是签名也使用SHA1来保证唯一性。
长期以来,人们都认为SHA1是十分安全的,至少大家还没有找到一次碰撞案例。
但这一事实在2017年2月破灭了。
CWI和Google的研究人员们成功找到了一例SHA1碰撞,而且很厉害的是,发生碰撞的是两个真实的、可阅读的PDF文件。
这两个PDF文件内容不相同,但SHA1值完全一样。
所以,对于一些大的商业机构来说, MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。
以上是关于Hash算法的「碰撞」的主要内容,如果未能解决你的问题,请参考以下文章
Hash碰撞(选做)
Java面试题之hashmap中用什么hash算法解决碰撞的?
hash碰撞POC
密码学系列之:碰撞抵御和碰撞攻击collision attack
Hash算法的应用
HashMap