一句话版本
一个房间里只要有 23 个人,就有超过一半的概率有两人同一天生日。原因是"配对"的数量随人数平方增长。 同样道理,输出 位的哈希函数,不需要试 次,只要试大约 次就能找到两个哈希值相同的输入。所以 256 位的 SHA-256 只提供 128 位的抗碰撞强度。
全文分三层:
- 通俗理解:生日悖论,哈希函数要满足的三个性质
- 实际用处:区块链、Git、证书,以及 MD5、SHA-1 被攻破的事件
- 数学原理: 的推导、Pollard rho 式的无存储碰撞搜索,附一次真实的截断碰撞实验
第一层:通俗理解
1.1 生日悖论
一年 365 天。问:一个房间里至少多少人,才能让"有两人同一天生日"的概率超过 50%?
直觉往往回答 183(365 的一半)。正确答案是 23。
关键在于,我们问的不是"有人和我同一天生日",而是"任意两人同一天"。23 个人可以组成 对,每一对撞上的概率是 ,253 对加起来,机会就相当可观了。
| 人数 | 至少两人同一天生日的概率 |
|---|---|
| 10 | 11.7% |
| 23 | 50.7% |
| 50 | 97.0% |
| 70 | 99.9% |
1.2 哈希函数是什么
哈希函数把任意长的数据压缩成固定长度的"指纹",比如 SHA-256 输出 256 位。好的哈希函数要满足:
| 性质 | 含义 | 理想难度( 位输出) |
|---|---|---|
| 抗原像 | 给定指纹,找不到对应的输入 | |
| 抗第二原像 | 给定一个输入,找不到另一个同指纹的输入 | |
| 抗碰撞 | 找不到任意两个同指纹的输入 | (生日界) |
第三条和生日悖论完全对应:碰撞攻击者可以自由选择两个输入,就像在房间里找"任意两人"同生日,所以只需要 次。
1.3 碰撞为什么危险
如果能找到两份文件 A、B 哈希相同:让别人对无害的 A 签名(签名实际签的是哈希值),这个签名就同样适用于有害的 B。
第二层:实际用处
哈希函数无处不在
- 区块链:比特币用 SHA-256 做工作量证明和区块链接;以太坊地址是公钥 Keccak-256 哈希的后 20 字节。
- Merkle 树:把成千上万笔交易哈希成一个根,可以用 个哈希证明某笔交易在区块里。
- Git:每个提交、文件都用哈希命名(历史上是 SHA-1,正在迁移到 SHA-256)。
- 数字签名、证书、密码存储、文件完整性校验。
碰撞攻击的历史
SHAttered 大约用了 次 SHA-1 计算,远少于生日攻击的 。这说明它利用的是 SHA-1 的结构弱点,而不只是生日悖论。
设计结论:要 128 位安全,抗碰撞场景就要 256 位输出。这就是 SHA-256 成为默认选择的原因。
量子计算机对哈希的影响
理论上的量子碰撞算法(BHT)可以做到 ,但需要海量量子内存,实际意义存疑。主流观点认为 SHA-256 和 SHA-3 在后量子时代仍然够用,基于哈希的签名(SPHINCS+)甚至是后量子标准之一,见《后量子密码》。
第三层:数学原理
3.1 生日界的推导
从 个可能值中独立均匀地取 个,全部不相同的概率是
用 ( 小时近似相等):
令碰撞概率为 ,解得
代入 ,,和 23 吻合。代入 ,。
3.2 手算例子:真实找一次碰撞
SHA-256 截断到 16 位
只取 SHA-256 输出的前 4 个十六进制字符(16 位,)。生日界预测大约需要 次。
依次哈希 msg0、msg1、msg2……并记录前缀,第 122 次尝试就撞上了:
| 输入 | SHA-256 前 16 个十六进制字符 |
|---|---|
msg114 |
98978261783e81fd |
msg121 |
9897dbca5f8d00ea |
两者前 16 位都是 9897。(用 Python 实际跑出,这次运气偏好。)
作为对比,要找一个前缀指定为 9897 的输入(第二原像),平均要试约 次。
3.3 不需要大内存的碰撞搜索
上面的方法要把所有见过的哈希存下来, 规模时内存吃不消。Floyd 判圈的思路可以解决:
把哈希函数 看成有限集合上的映射,从 出发反复迭代 。因为集合有限,序列迟早进入循环,形状像希腊字母 。进入循环的那一刻,两个不同的点映射到了同一个点,这就是一次碰撞。
用"龟兔赛跑"(一个每次走一步,一个每次走两步)就能在 时间、 内存内找到它。这和Diffie–Hellman与离散对数里解离散对数的 Pollard rho 是同一个思想。van Oorschot–Wiener 的并行版本还能让成千上万台机器同时搜索。
3.4 为什么生日界不能被"设计"掉
生日攻击是通用的:它不看哈希函数的内部结构,对任何 位输出的函数都有效。所以抗碰撞强度的上限永远是 位。密码学家能做的只有一件事:把输出加长。
总结
| 层次 | 要点 |
|---|---|
| 直觉 | 23 人就有一半概率撞生日,因为"对"的数量是平方级 |
| 数学 | 次就有一半概率碰撞 |
| 安全 | 位哈希抗碰撞最多 位;所以用 SHA-256 |
| 历史 | MD5(2004)、SHA-1(2017)相继被攻破,都是结构弱点 + 生日思想 |