在哈希函数的世界里,有些名字曾经光芒万丈,如今却成了危险的代名词。MD5和SHA-1就是这样的存在。它们曾是整个互联网的守护者,但最终在数学家的攻势下轰然倒塌。这一节,我们就来聊聊这些算法的兴衰,以及那个让它们失效的致命漏洞——碰撞攻击。
MD5:从英雄到阶下囚
MD5(Message Digest Algorithm 5)诞生于1991年,由罗纳德·李维斯特(RSA中的R)设计。它一出现就成为应用最广泛的哈希函数,几乎无处不在:文件校验、密码存储、数字签名,甚至早期的SSL证书也用MD5。它的输出是128位,看起来足够安全——要找到碰撞,理论上需要尝试2^64次,这在当时是不可想象的。
但密码学的历史告诉我们:永远不要相信“看起来安全”。2004年,国际密码学大会上发生了一件轰动全球的事。中国密码学家王小云教授宣布,她找到了MD5的碰撞——两个不同的文件产生了完全相同的MD5值。更惊人的是,她的方法不是暴力破解,而是一种巧妙的数学分析,可以在普通计算机上快速生成碰撞。
这个发现如同一颗炸弹,彻底宣告了MD5的死刑。从那以后,MD5不再被视为安全的哈希函数。任何依赖MD5的安全系统都变得脆弱不堪。
什么是碰撞攻击?
要理解为什么碰撞攻击如此致命,我们得先明白哈希函数的“抗碰撞性”是什么意思。
假设有两个不同的输入A和B,如果它们的哈希值相同,我们就说发生了一次“碰撞”。一个安全的哈希函数,应该让找到这样的碰撞在计算上不可行。因为输出长度有限,理论上碰撞一定存在,但好的哈希函数应该让它们极难发现。
碰撞攻击就是找到两个不同的输入,使它们的哈希值相等。如果攻击者能做到这一点,就能玩出很多花样。比如:
- 数字签名欺诈:你让一个合法文件A签了名,攻击者找到另一个恶意文件B,它的哈希值与A相同。这样,B就可以冒充A的签名。
- 文件完整性破坏:攻击者可以把一个正常软件替换成含有恶意代码的软件,只要哈希值相同,用户就无法察觉。
注意,碰撞攻击和“原像攻击”不同。原像攻击是给定哈希值找输入,那更难。但碰撞攻击只需要找到任意两个输入相同哈希,相对容易些。对于MD5,这种攻击已经成为现实。
SHA家族:接力与坠落
SHA(Secure Hash Algorithm,安全哈希算法)是由美国国家安全局(NSA)设计、国家标准与技术研究院(NIST)发布的一系列哈希函数。SHA家族有很多成员:SHA-0、SHA-1、SHA-2、SHA-3。
SHA-1诞生于1995年,输出160位,被设计用来替代MD5。在很长一段时间里,SHA-1被认为是安全的,广泛应用于TLS证书、Git版本控制等。但随着计算机性能的提升和密码分析技术的进步,SHA-1的影子也日益逼近。
2005年,王小云教授再次出手,宣布找到了SHA-1的碰撞攻击方法,将理论复杂度从2^80大幅降低。虽然当时还不能在实际中生成碰撞,但这敲响了警钟。2017年,Google和CWI研究所联合发布了SHAttered攻击,成功生成了两个不同的PDF文件,它们的SHA-1值完全相同。这标志着SHA-1正式死亡。
SHA-1的碰撞文件长什么样?你可以想象两个内容完全不同的PDF,但它们的SHA-1值是一样的。其中一个可能是合法的合同,另一个是篡改过的版本,但数字签名却无法区分。
为什么碰撞攻击越来越容易?
这些攻击的细节非常复杂,涉及深奥的数学,但我们可以用一个简单的比喻来理解。
想象哈希函数是一个把大文件塞进小盒子的过程。因为盒子很小,必然有很多不同的文件会塞出相同的形状。设计哈希函数就是要让这些“相同形状”极其罕见,而且难以找到。MD5和SHA-1的设计存在某些数学结构上的弱点,就像盒子有一些缝隙,让攻击者可以顺着缝隙找到两个文件,恰好挤成相同的形状。
随着密码学家对这些结构的理解越来越深,攻击效率也越来越高。到今天,在一台普通电脑上生成MD5碰撞只需要几秒钟,生成SHA-1碰撞也只需要一定计算资源(比如数百美元云服务)。
接力者:SHA-2和SHA-3
在SHA-1还在服役时,NIST就已经意识到需要更强大的替代品。2001年,他们发布了SHA-2家族,包括SHA-224、SHA-256、SHA-384、SHA-512等。SHA-2的输出更长(最长512位),设计更复杂,至今仍被认为是安全的。你用的比特币,就是SHA-256的忠实用户。
然而,密码学家们总喜欢留一手。万一哪天SHA-2也被攻破呢?于是NIST在2012年举办了一场全球竞赛,征集新一代哈希函数。经过几轮筛选,SHA-3(原名Keccak)胜出,成为新的标准。SHA-3的设计与SHA-2完全不同,即使未来SHA-2倒下,SHA-3也能顶上。
如今,SHA-2和SHA-3并存,都是安全的选择。而MD5和SHA-1已经被彻底抛弃——任何还在用它们的系统,都应该尽快升级。
给读者的启示
MD5和SHA-1的兴衰告诉我们几个道理:
- 没有永恒的密码。今天安全的算法,明天可能就变成定时炸弹。
- 公开竞争是最好的检验。像SHA-3这样的全球竞赛,能让算法接受全世界密码学家的审视,减少隐藏漏洞的可能。
- 不要自己发明哈希函数。这比发明加密算法还要危险。用经过验证的标准算法,比如SHA-256或SHA-3。
- 关注安全公告。当专家警告某个算法不再安全时,一定要及时迁移。
在下一节,我们会看到哈希函数在现实生活中的种种应用——从密码存储到文件校验,从Git到区块链。你会发现,这些安全的哈希函数,正在默默守护着你数字生活的每一个角落。