哈希算法全家桶:一文看懂 MD5 到 SHA-3 的演进
什么是哈希算法?
哈希算法,一句话:把任意长度的数据压缩成固定长度的”指纹”。
你给它一本《三体》三部曲,它输出 256 位。你给它一个字母 “a”,它还是输出 256 位。输入可以千变万化,输出长度永远不变。这跟压缩完全是两码事——压缩可逆,哈希不可逆。哈希是单向阀门,数据进去就出不来了。
我第一次意识到哈希的威力,是大二做文件去重。一个硬盘里塞满了重复照片,我写脚本算每个文件的 MD5,相同哈希的就是重复。半小时清出 30G 空间。那瞬间突然明白了——哈希不只是课本上的”消息摘要”,它是真正能干活的东西。
从那以后,我陆陆续续把主流哈希算法都摸了一遍。这篇文章就是我的笔记整理:从 MD5 到 SHA-3,从算法原理到选型决策,帮你建立一个完整的哈希家族认知地图。
一个好哈希算法长什么样?
不管哪个家族、哪一代,密码学哈希必须同时满足五条硬指标:
- 确定性:同一个输入,天涯海角、什么机器、什么语言,输出必须一字不差
- 单向性:给你哈希值,你算不回原始输入。不是”很难算”——是计算上不可行
- 雪崩效应:输入改一个比特,输出天翻地覆。你不能从输出的变化反推输入改了什么
- 抗碰撞性:找不到两个不同的输入产生相同的哈希。这是最难的一条,也是评价一个算法好坏的核心标尺
- 抗第二原像性:给定一个输入 M,找不到另一个 M’ 使得它们的哈希相同。听上去像第 4 条,但要求更低一些——碰撞是你随便挑两个能碰撞的输入就行,第二原像是给你指定了一个输入让你找它的”孪生兄弟”
这五条里,第 4 条决定了算法的寿命。SHA-1 被宣判死刑,就是因为碰撞攻击从”理论”走到了”实践”。
算法家族逐个看
MD 系列:哈希的旧王朝
MD(Message Digest)系列是 Ron Rivest 的作品。MD2 诞生于 1989 年,针对 8 位机优化;MD4 诞生于 1990 年,追求速度但安全上妥协太多;MD5 在 1992 年登场,128 位输出,是这一脉的巅峰,也是终结。
MD5 的结构影响了一个时代——SHA-1、SHA-2 的总体架构都能看到它的影子。它的速度极快,实现极度简单,20 行 C 代码就能跑。
但快,恰恰是它的死穴。
2004 年,山东大学王小云教授的团队公布了完整的 MD5 碰撞攻击。2008 年,攻击者用 MD5 碰撞伪造了 CA 证书,直接打穿了当时的 PKI 体系。到了今天,在个人电脑上几分钟就能算出 MD5 碰撞。
我 2016 年入职第一家公司时,发现用户密码还在用 MD5(password) 存。一时语塞。跟 leader 说了半天才推动迁移到 bcrypt。说实话,很多老系统里的 MD5 不是因为开发者不关心安全,而是代码太老、依赖太多、没人敢动——但这不是继续用它的理由。
现状:仅用于非安全场景——校验和、数据去重、Git legacy 对象标识。任何涉及安全的场景,别碰 MD5。
SHA-1:被 Google 送上刑场
SHA-1 由 NSA 设计,NIST 在 1995 年发布。输出 160 位,比 MD5 的 128 位多了一层保护。它是 HTTPS 证书、Git 版本控制、软件分发签名的基础设施。
但学术界对它一直不放心。2005 年理论攻击出现,2017 年 Google 的 SHAttered 项目实战成功——生成了两个不同内容的 PDF,SHA-1 哈希值完全一样。成本大约 11 万美元的云计算资源。
这相当于什么概念?相当于有人做出了两把钥匙能开同一扇门,而且用的是真金白银在商用的云上做到的。从那天起,SHA-1 在安全圈正式宣告死亡。
各大浏览器在 2017 年后彻底关闭了 SHA-1 证书支持。Git 也在缓慢但坚定地向 SHA-256 迁移——虽然因为兼容性问题,这个过程预计还要很多年。
SHA-2:当代哈希的绝对主力
SHA-2 家族(SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256)才是今天真正的王者。
它和 SHA-1 的架构同源(都是 Merkle-Damgard 结构),但内部运算更复杂、输出更长、安全边界更高。核心成员使用情况:
- SHA-256:使用最广。比特币挖矿、TLS 证书、JWT 签名、文件校验,能想到的场景几乎都有它。256 位的输出,暴力碰撞需要约 2^128 次运算——在热力学极限下也不可行
- SHA-512:256 位输出还不够安心的场景用这个。大文件签名、合规要求高的环境。内部用 64 位运算,在 64 位 CPU 上速度甚至比 SHA-256 还快
- SHA-384:SHA-512 的截断版。速度没优势,但某些政府合规场景强制要求
SHA-2 有一个共同的架构弱点:长度扩展攻击。因为 Merkle-Damgard 的链式结构,如果攻击者知道 H(M) 和 M 的长度,就能算出 H(M + padding + 额外数据) 而无需知道 M 本身。这是 HMAC 的设计动力——HMAC 用双重哈希堵住了这个漏洞。
我在给一个内部 API 做签名方案时,一开始直接用了 SHA-256(secret + message),后来被人指出有长度扩展风险。改用 HMAC-SHA256 后,问题根治。这就是一个活生生的教训——哈希算法本身安全,不代表你的使用方式安全。
SHA-3:另起炉灶的后备方案
SHA-3 走了一条和 SHA-2 完全不同的路。它基于 Keccak(读作 “ketchak”),来自比利时团队,采用海绵结构(Sponge Construction)——数据被”吸收”进状态、“挤压”出哈希,而不是 SHA-2 那种逐块链式处理。
海绵结构有几个天然优势:
- 免疫长度扩展攻击,不需要 HMAC 那套额外操作
- 理论抗量子性更好
- 结构灵活,可以输出任意想要的哈希长度
2015 年,NIST 正式把 SHA-3 纳为标准(FIPS 202),但它不是来取代 SHA-2 的——它是”后备”。意思是:万一有一天 SHA-2 被发现有严重问题(虽然目前没迹象),整个行业可以立刻切换到 SHA-3,不至于抓瞎。
现实情况是:SHA-3 目前使用量远低于 SHA-2。不是因为不好,而是因为没必要换。软件生态已经深深绑定了 SHA-2,迁移成本巨大。再加上 SHA-2 在现阶段足够安全,没有动力去换。
可以这么类比:SHA-2 是你家用了十年的大门锁,质量过硬。SHA-3 是你早已备在抽屉里的另一把全新款锁——设计更先进,但换锁太麻烦,旧锁又没坏,于是就一直放着备用。
BLAKE:速度优于安全冗余的新锐
BLAKE 是目前速度最快的安全哈希之一。它的故事很有意思——它是 SHA-3 竞赛的第二名(仅次于 Keccak),但在性能上吊打所有参赛者。
BLAKE2 是它的优化版,比 MD5 还快,安全性却和 SHA-3 一个级别。后来又在 BLAKE2 基础上推出了 BLAKE3——更快、支持并行、支持增量处理,设计目标瞄准了高吞吐量场景。
不过 BLAKE 没有 NIST 标准背书,所以正式合规场景还得切回 SHA-2 或 SHA-3。适用场景:需要高性能的内部系统、数据完整性校验、密码哈希(配合 Argon2)、大文件去重。不需要外界审计的场合,BLAKE 是速度达人。
SM3:中国的密码学国标
SM3 是中国的商用密码哈希标准(GM/T 0004-2012),输出 256 位。结构和 SHA-256 类似(Merkle-Damgard),但在消息扩展和压缩函数上做了调整——消息扩展更复杂、每轮使用的常量不同。
在国内的银行、政务、通信系统里,SM3 是强制或推荐使用的哈希算法。如果你的产品需要在中国通过商用密码合规认证,SM3 基本是绕不开的选项。
安全性方面,SM3 经过了大量密码分析,就目前公开文献来看没有有效碰撞攻击。但坦率说,它的国际学术审查远没有 SHA-2 和 SHA-3 那么深。
一图看懂各算法的安全状态
| 算法 | 输出位数 | 安全状态 | 抗碰撞 | 主要用途 | 标准 |
|---|---|---|---|---|---|
| MD5 | 128 | 已攻破 | 否 | 校验和、去重(非安全) | RFC 1321 |
| SHA-1 | 160 | 已攻破 | 否 | Git 遗留、历史兼容 | FIPS 180-4(退役中) |
| SHA-256 | 256 | 安全 | 是 | TLS、区块链、签名 | FIPS 180-4 |
| SHA-512 | 512 | 安全 | 是 | 高安全场景、合规 | FIPS 180-4 |
| SHA-3 | 224/256/384/512 | 安全 | 是 | 后备方案、灵活场景 | FIPS 202 |
| BLAKE3 | 可变 | 安全 | 是 | 高性能内部系统 | 无(社区标准) |
| SM3 | 256 | 安全 | 是 | 中国商密合规 | GM/T 0004 |
文本决策流程图
选算法就像选车——没有绝对的最好,只有最适合你的。
拿好你的需求,跟着走就行:
你对哈希的需求是什么?
│
├─ 只做校验和/去重,不涉及安全
│ → MD5。够快、够用、生态最广
│
├─ 需要安全,但不涉及中国合规
│ ├─ 性能敏感 + 标准不是硬要求
│ │ → BLAKE3。吞吐量吊打 SHA-2
│ ├─ 需要广泛兼容 + 有标准背书
│ │ → SHA-256。市面上几乎没对手
│ └─ 特别高安全或合规要求(如 FIPS 140-2 Level 4)
│ → SHA-512。256 位输出还不够就上 512
│
├─ 需要中国商用密码合规
│ → SM3。银行、政务系统的标准配置
│
└─ 在做规划,为未来储备
└─ 关注 SHA-3。如果 SHA-2 出事,它是第一备选
有一点需要强调:HMAC 不是哈希算法,而是在哈希之上的消息认证方案。如果你的场景涉及认证(确保消息来源可靠),不要直接用裸哈希——一定上 HMAC,或者采用带内置认证的构造(如 BLAKE2 的 keyed 模式)。
常见误区
误区一:“SHA-256 破解了怎么办”
这是我最常被问到的问题之一。答案是:目前没人能破解 SHA-256。连理论上有效的 2^128 以下的攻击都没有。而且就算有一天量子计算机成熟了,Grover 算法也只能把安全性从 256 位降到 128 位——128 位安全强度仍然是不可暴力搜索的。这个宇宙里没有足够多的能量来翻转 2^128 个比特。不是”暂时做不到”,是物理定律级别的做不到。
误区二:输出越长越安全
不完全是。安全性取决于算法设计和输出位数的综合因素。SHA-512 的 512 位输出并不代表它比 SHA-256”安全一倍”——抗碰撞强度是 256 位和 128 位的关系,不是线性翻倍。而且在大多数实际应用里,SHA-256 的安全余量已经远超攻击者能触及的天花板。选 SHA-512 更多是满足合规清单,不是实际攻防需要。
误区三:SHA-3 比 SHA-2 好,应该立即替换
架构上 SHA-3 确实更优——海绵结构比 Merkle-Damgard 更现代、攻击面更小。但软件行业不是只看算法的优雅程度。SHA-2 经过了二十多年的实战检验,硬件加速(Intel SHA Extensions)、协议集成(TLS 1.3、DNSSEC、X.509)、法律合规都已经完备。SHA-3 目前没有压倒性的理由让你放弃 SHA-2。正确的心态是:用 SHA-2 保持兼容,关注 SHA-3 保持储备。
我之前的团队曾认真讨论过要不要把所有签名从 SHA-256 切到 SHA-3。最终结论是:投资回报比太低。切换成本巨大(上游依赖、客户系统、合规审计),而安全增益在当前威胁模型下几乎为零。不如把精力花在加强密钥管理上。
常见问题
Q: MD5 和 SHA-256 本质区别在哪?
不是简单的位数区别。MD5 整个内部结构已经有已知的碰撞构造方法——攻击者可以主动制造碰撞。SHA-256 目前没有任何已知的有效碰撞方法。一个是”已知怎么攻破”,一个是”尚未找到攻击方法”——这是本质上的鸿沟。
Q: 哈希和加密到底哪里不一样?
哈希是单向的,加密是双向的。哈希没有密钥、不可逆——进去了出不来。加密有密钥、可逆——拿钥匙能解密回原文。举个生活里的例子:哈希像绞肉机,肉馅不可能变回五花肉;加密像保险箱,放进去锁上,有密码还能原样拿出来。
Q: 加盐到底加的是什么?
盐是一个随机字符串,拼在原始数据前面或后面再一起哈希。目的是让两个相同密码的人产生不同的哈希值,同时让预先算好的彩虹表彻底失效。不加盐 MD5("123456") 永远是同一个值,攻击者查表秒破。加了足够长的随机盐之后,每个用户即使密码相同,哈希值也完全不一样。
Q: SHA-256 适合存密码吗?
不适合。SHA-256 的设计目标是”快”——而密码存储要的是”慢”。GPU 每秒可以算几亿次 SHA-256,尝试十亿个密码就是几分钟的事。密码哈希应该用 bcrypt(老牌稳妥)、scrypt(吃内存)或 Argon2(最新推荐),它们故意加大计算量和内存消耗,让暴力破解寸步难行。
Q: BLAKE3 会不会是下一代标准?
BLAKE3 在性能上的优势确实令人瞩目——它比 SHA-256 快一个数量级,且天然支持并行和增量计算。但它没有 NIST 背书,也没有像 SHA-2 那样嵌入到全球的数字基础设施里。它适合需要高性能的内部系统、非标准化的场景,但短期内不可能取代 SHA-2 成为强制标准。目前看最可能的发展方向是:NIST 维持 SHA-2/SHA-3 路线,BLAKE3 在开源和工业界走并行路径。
Q: 一个数据有多个哈希值正常吗?
正常。同一个文件用 MD5 算出一个 128 位的指纹、用 SHA-256 算出一个 256 位的指纹、用 SHA-3 算出又另一种——因为它们是完全不同的算法。这就像同一个人的信息用身份证、护照、驾照分别记录,载体不同、格式不同,但都指向同一个实体。实际中很多下载站同时给出 MD5、SHA-1 和 SHA-256 三种校验和,就是为了不同验证深度的需要。