本节摘要:MD5、SHA-1、SHA-2、SHA-3 四代同堂,境遇天差地别:MD5 的碰撞攻击在 2004 年进入"秒杀"区间,SHA-1 在 2017 年被公开实验钉死,SHA-2 至今无恙,SHA-3 则是刻意不同构的"结构保险"。本节沿时间线复盘每一次退役的攻防细节,解释长度扩展攻击为何专门袭击 Merkle-Damgård 结构,以及选型时如何留退路。
MD5(1991,128 位):罗纳德·李维斯特系列摘要算法的第五代,整个 1990 年代无处不在。1996 年压缩函数的缺陷已被点名,2004 年王晓云团队在美密会上宣布解析法构造碰撞——不再穷举,直接按差分路径"算出"一对同摘要的消息,计算成本从 2⁶⁴ 的生日界跌到可手数;2008 年安全研究者用"选择前缀碰撞"伪造出一张被浏览器信任的 Rogue CA 证书,可以给任意网站签发假身份。NIST 随即要求 2010 年底前全面停用其签名用途。今天 MD5 只剩非安全用途(如去重缓存键),且新代码一律不应再碰。
SHA-1(1995,160 位):NSA 基于同为 Merkle-Damgård 结构的 SHA-0 改良,输出比 MD5 多 32 位。2005 年王小云团队给出理论碰撞路径(约 2⁶⁹),业界开始倒计时;NIST 2011 年宣布弃用、2013 年禁止签名用途。钉死棺木的是 2017 年 Google 与 CWI 的 SHAttered 实验:以约 2⁶³ 次运算(百万年 GPU 算力折合几百年的量级,租用云 GPU 约 11 万美元级别的成本模型)公开产出两份 SHA-1 摘要相同、内容迥异的 PDF。Git 随即启动对象格式的 SHA-256 迁移,各大浏览器同年将 SHA-1 证书全线判死。
SHA-2(2001,224/256/384/512 位):结构与 SHA-1 同族但轮函数大幅加固,至今二十余年没有实用碰撞。它是当前 TLS 证书签名(sha256WithRSA、ECDSA-P256 配 SHA-256)与绝大多数校验场景的现役主力。

Merkle-Damgård 结构(MD5、SHA-1、SHA-2 共用)有个容易被忽视的副作用:摘要 h = H(m) 本质是中间链状态的直出,知道 h 后可以不重算任何东西地续接新数据——给定 H(secret∥m),攻击者无需知道 secret 就能算出 H(secret∥m∥padding∥额外数据)。这叫长度扩展攻击,直接判死了"H(密钥∥消息) 当 MAC"这类朴素设计——3.5 节 HMAC 的双层包裹(内外两圈哈希、密钥异或常量)正是为斩断这条续接链而设计的。
SHA-3 换了完全不同的海绵结构:吸收相挤压相分离,内部状态不外露,长度扩展从原理上不存在。它 2007 年由 NIST 全球征集(与 AES 竞赛同一治理范式)、2012 年 Keccak 胜出、2015 年定稿 FIPS 202。要理解 SHA-3 的真实定位:它不是 SHA-2 的升级替代——SHA-2 没有病——而是一份结构保险:如果哪天 SHA-2 的 Merkle-Damgård 结构被找到捷径,产业界可以无缝切换到结构完全无关的 SHA-3,不必重演 SHA-1 式的全网大迁移。此外它自带可变输出长度的 SHAKE128/256,在密钥推导与流式场景很顺手。追求极致性能的现代项目则常选 BLAKE2/BLAKE3——同为无长度扩展问题的结构,速度比 MD5 还快。
用标准库把四代的"体温"量一遍:
import hashlib, time data = b"x" * (1 << 20) # 1 MB 样本 for name in ("md5", "sha1", "sha256", "sha512", "sha3_256", "blake2b"): h = hashlib.new(name) t0 = time.perf_counter() for _ in range(20): h = hashlib.new(name) h.update(data) dt = time.perf_counter() - t0 print(f"{name:8s} 摘要 {h.digest_size * 4} 位 吞吐约 {20 / dt:8.0f} MB/s")
新代码的默认答案只有两行:通用场景 SHA-256 或 BLAKE 系列;口令存储不用它们——那是下一节的主角。
⚠️ 常见坑:看到"SHA"就当安全。SHA-1 顶着"安全散列算法"的名号死透了;同理,用 SHA-256 存口令是错的(太快,见 5.3),用它做校验是对的——算法没有万能,只有场景匹配。
证书与数字签名的配套哈希:SHA-256 起步,签发体系早已拒绝 SHA-1。文件校验与对象存储:SHA-256 或 BLAKE2,兼顾速度与安全。口令存储:Argon2、scrypt 或 bcrypt,专用慢哈希,与通用哈希不通用。密钥推导与 HMAC 内核:SHA-256,稳妥且硬件加速普及。国密合规场景:SM3 对应上述各位置,输出同为 256 位。一句话版本:SHA-256 是默认答案,快哈希防不住口令,慢哈希不必用于校验——各归各位,安全的一半在选型。
SHA-2 家族包含 224、256、384、512 四个常用位宽,其中 SHA-224 与 SHA-256 共享同一套运算、仅初始值与输出截断不同;SHA-384 则是 SHA-512 的截断版——位宽之间不是四种算法,而是两套内核加裁剪。TLS 证书签名现役主力是 SHA-256 搭配 RSA 或 P-256,SHA-384 常见于高安全档位的 P-384 组合。选型时记住一句:位宽跟曲线走,不要混搭出"384 位哈希配 128 位曲线"的错配组合。
算法兴衰看清了,真正的事故高发区在应用端。下一节走查三大场景——文件校验、口令存储、默克尔树——每一个都有亲手可跑的代码与一段真实事故。