SHA-1是啥?

发布时间:2026/7/23 7:13:11
SHA-1是啥? 一句话SHA-1是Hash算法的中广泛使用的一种。哈希Hash又称为散列或者杂凑是一种算法。这种算法接受任意长度的数据输入然后给出一个固定长度的输出。↑ 图2 Hash示意图如图2所示Hash函数的输出反而没有特别的意义一个设计一个优良的Hash函数需要尽量满足如下条件通过输入可以容易地计算出输出很难从给定的输出反推出输入即不可逆性不能修改输入哪怕是微小的修改而使得输出不变不能找出2个不同的输入使得输出一样Hash的输出值称为散列值或者数据的摘要通常可以作为数据的指纹这在密码学领域有重要的意义。SHASecure Hash Algorithm是由National Institute of Standards and Technology (NIST) 制定的作为U.S. Federal Information Processing Standard (FIPS)的散列函数家族。↑ 图3 SHA家族这次被发现碰撞的是SHA-1散列算法是目前依然使用非常广泛的一种算法它的输出是160个bits图1中用了40个16进制数来表示。SHA-1被发现碰撞之所以能成为大新闻和它的应用场景分不开。大新闻做了啥虽然说在2005年文献[2]已经提出了复杂度小于的理论碰撞在2013年文献[5]将这一数字优化到 但是他们都是理论分析并没有给出实证。在不见棺材不掉泪的情况下给出一个实例才是最好的。所以The first collision for full SHA-1一文创造了第一个碰撞的实例。他们基于[5]的研究使用一种名为相同前缀碰撞攻击identical-prefix collision attack的方法即2条消息的前缀P是一样的主要寻找2个数据对使得2个完整消息的SHA-1输出相等而后缀S可以是任意值。一旦这样的数据对找到就严重违背了“不能找出2个不同的输入使得输出一样”这一要求也就宣布了SHA-1算法已经变得不安全。当然找到这样一个碰撞的难度很大得益于研究人员对算法的不断优化和GPU技术的发展现在终于实现了在 复杂度下的实际碰撞攻击。如果认为图1还是一个巧合的话实际上这样的巧合发生概率趋近于0论文中还给出了另外一组实例如图4所示。↑ 图4 SHA-1碰撞实例这次的实际攻击是拿JPEG开刀所以PDF中是2幅图像不同也算是比较有视觉说服力的实例。按照惯例这次碰撞攻击的细节包括技术细节和源代码将会在以后条件成熟时公开。以Git为例Git的本质是一种内容寻址的文件系统Content-addressable filesystem也就是说Git内部是通过键值对的方式存储的而检索的本质是通过键来查找对应内容。因此向Git提交的任意内容都会通过Hash算法得到一个唯一的键以后可以通过这个键唯一地检索到存储的内容。而Git使用的Hash算法正是SHA-1。接下来验证这一点。以一个文件为例Git对于该文件取Hash的方法如下sha1(‘blob ’ filesize ‘\0’ filedata)↑ 图5 Git中的Hash图5中3个红框代表了3次hash操作。第一次是使用openssl提供的sha1算法计算hash第二次是git提供的 hash-object方法计算hash第三次是实际创建了一个仓库并在commit后检查hash三次计算的结果完全一致说明了Git在内部完全依赖SHA-1算法作为其hash算法。实际上Git并不关心文件或者处理的对象的名称而只通过Hash值来区分他们。在Git的世界里一个对象的Hash就是一个对象的唯一ID。如果ID可以伪造那么就没有然后了。接下来分析Git在遇到Hash碰撞的时候如何处理。是不是很期待再来一发截图玩坏Git然而现在并不行。实际情况由于碰撞需要的计算量依然远超过PC的能力以及技术细节并没有完全公开真实的情况还有待验证。而且Git并不是直接计算文件的Hash所以图1给出的样例碰撞不会影响Git的运作。要不“稍微”修改一下Git的实现人为创造碰撞试试。文献[1]通过修改源码的方式构造了一个简化的4 –bit SHA1版本来探究了碰撞的情况。实验的结果是在不少常见场景下Git不报错而实际上仓库已经出现了不同类型的损坏。一种简单的修复方法是报错并提示用户虽然此时Git不能正常运作但是可以及时止损。再看HTTPS相比Git的问题HTTPS使用的证书情况似乎好很多。SHA-1的不安全性王小云教授早就在2005年就已经指出了[2]。近几年各大公司也正逐渐的淘汰SHA-1对于SSL证书Windows已于2017年1月1日起停止支持SHA1证书。对于代码签名证书Windows早在2016年1月1日就停止接受没有时间戳的SHA-1签名的代码和SHA-1证书。Google的Chrome浏览器已经逐步地废弃了SHA-1证书支持现在最新版的Chrome已经彻底不支持了。Mozilla自2017 年 1 月1 日后不再信任SHA-1证书。……可以看到不再支持SHA-1只是一个时间问题。或许这次的大新闻将加速这一进程。So far so good。这是由于对于大公司而言更换新的证书很简单因为不涉及到客户端的分发。真正的挑战还是客户端对于写应用程序的工程师来说困难在于老旧的客户端不支持某些新特性而在安全领域是倒过来的困难的是老旧的客户端支持了过时的特性。所以并不是大公司更新了证书用户就可以高枕无忧。以HTTPS为例只要浏览器还支持SHA-1那么攻击者就可以伪造一个SHA-1签名的证书来冒充即便被攻击的对象早已升级成了更安全的证书。因为浏览器会直接信任收到的SHA-1假证书并不知道新证书的存在。这种方式的攻击只能从各方面来缓解真正要杜绝只能让浏览器彻底不支持SHA-1。以下以Windows为例其它产品情况类似或者更糟吧幸运的是我们生活在一个科技快速更新的时代Windows 10已经迭代了多个版本大家觉得够好用的Windows 7 实际上都是8年前的“老古董”了好在老家伙们都老当益壮没有问题。不幸的是Windows XPWindows XP在SP3之后才支持SHA-2才能够淘汰SHA-1。问题国内还有多少Windows XP的用户几百万他们打死不升级系统还会在乎是SP几么。但是又不能彻底放弃XP难道只有时间才能告诉我们答案……历史的行程和改进建议这次大新闻还给出了攻击的代价。相比MD5可以用手机秒算而言SHA-1的代价是110个GPU一年。这个代价对于中小企业和个人还是很难接受但是对于大公司而言是可以做到的。更别忘了摩尔定律还在垂死挣扎拥有更加高效更加廉价的计算资源也是历史的行程不能不考虑。↑ 图6 代价对比所以在安全领域一种算法用到天荒地老是不太现实的。实际上每一种密码学算法都有其预估的生命周期“道高一尺魔高一丈”不断的更新迭代才铸就了密码学今日的辉煌。例如文献[3]给出了Hash的生命周期。↑ 图7 Hash的生命周期简言之红色已死黄色有小病绿色的活蹦乱跳。这次的新闻给SHA-1画上了句号目前依然存活的是SHA-2例如SHA-256和SHA-3Keccak是最终胜出者。所以改进的思路倒是很简单新的项目全用SHA-2或者SHA-3就可以了。SHA-2已经非常成熟直接拿来用即可。SHA-3的各种高效实现也层出不穷这些都是依然安全的Hash算法Keccak真是一个年轻充满活力的算法个人推荐。对于正在开发的项目能换的赶紧换不能换的也要创造条件换。毕竟以后摊子大了更加不好办。对于已有的项目比如Git这种情况想更换也就只能慢慢迭代更新了。这确实是有较大的工程量。如这里[4]提到的单单是替换硬编码的unsigned char[20]可能就需要不少精力。SHA-256和SHA-3的输出都不止160bits20字节的空间是不够的此外对于一些安全不敏感的应用也可以不用换。MD5理论上已经“死了”十多年了但是还是有不少地方在使用它们。毕竟软件工程上有牵一发动全身的特点如果仅仅为了替换一个算法而引入了更多不该有的bug反而得不偿失。最后是对于普通用户的建议有条件就更新。消费电子产品买新不买旧在历史的行程上看还是总体正确的。即便硬件不能更新软件也要及时更新这能解决很多安全上的问题虽然也可能带来一些小的麻烦。