生日悖论与哈希碰撞:为什么 256 位哈希不怕“撞名”,短哈希却一撞就中 图 1
生日悖论与哈希碰撞:为什么 256 位哈希不怕“撞名”,短哈希却一撞就中 · 图 1

教室里的反直觉:23 个人就够一半概率

先说一个概率事实:一个房间里只要 23 个人,就有超过约一半的概率存在两个人同一天生日;57 个人时概率接近 99%。听起来太多——一年有 365 天,怎么可能 23 个人就撞上?错觉来自问法:人们默认问“有人和我同一天生日吗”,那确实需要两三百人才过半;但“任意两人之间”的组合数增长是平方级的,23 个人之间有 253 对组合,每对都是一次抽奖。这就是生日悖论:不是悖论,是直觉跟不上组合数学。

搬到哈希上:碰撞比原像便宜得多

哈希函数把任意长度输入压缩成固定长度的输出。安全语境里有两类攻击目标。第一类叫原像攻击:给定输出,倒推一个能算出它的输入——对 n 位哈希,暴力尝试平均需要约 2 的 n 次方次运算。第二类叫碰撞攻击:找任意一对不同的输入算出同一个输出——由于生日悖论,只要约 2 的 n/2 次方次尝试就能有半数把握撞上。安全参数里的“有效安全强度减半”就是这么来的:256 位输出的哈希,抗碰撞强度是 128 位级别。

对 SHA-256 来说,128 位级别的穷举在物理上仍然不可行——哪怕把全地球的算力堆上也只是零头,所以“比特币地址会不会恰好撞出一个别人已有的地址”这种担心,数学上可以当作不会发生;个性化地址(vanity 地址)本质上就是拿算力慢慢耗出前缀,性质上与此同源。真正危险的是另一件事:攻击者不用穷举,而是找到哈希算法结构里的数学捷径。

短命的前辈:MD5 与 SHA-1 是怎么倒下的

MD5 输出 128 位,按生日界理论强度只有 64 位级别,更糟的是它的内部结构被找到了构造碰撞的方法:2004 年前后,研究者展示了可在普通计算机上秒级构造出两个 MD5 相同的文件。此后出现著名的“哈希碰撞双胞胎”实验:两份内容不同的 PDF 共用一个 MD5,可被用来在旧式安全流程里偷换文件。SHA-1 的处境类似,理论攻击逐年收紧,2017 年由谷歌团队与合作者公开了实际的碰撞实例,此后各大浏览器与证书体系集体淘汰 SHA-1。注意一个容易被忽略的层次:找到碰撞靠的是数学结构缺陷加算力,而不是漫无目的地赌运气——这正是密码学需要“结构安全加长度足够”两条腿的原因。

一个直觉算术:赌中比特币地址要多久

假设有一台超级计算机每秒能算十亿次哈希,穷举 128 位的一半(约 3.4 乘 10 的 38 次方次)需要的时间远超宇宙年龄。工程上正确的担心从来不是“撞中某个地址”,而是算法被发现新的结构缺陷、或实现环节(如签名拼错消息)引入弱点——这也是为什么系统级迁移(比如签名方案升级)会按“安全余量”提前很多年启动。

快速问答

截短的哈希不能当身份用吗? 做索引、布隆过滤器这类允许误报的场景没问题;做签名摘要或凭证,长度必须由安全强度反推,不能省。生日攻击能攻击比特币吗? 理论上适用,但 256 位长度把成本推到不可达,现实风险在别处。

常见误区

第一,把生日攻击理解成“任何哈希都能被轻易找到碰撞”——生日界给出的是穷举成本的量级,真正的灾难来自结构缺陷让成本进一步塌方,MD5 与 SHA-256 的差距就在这里。第二,认为碰撞等于伪造身份:多数场景里碰撞不直接等于作恶可行,但若安全逻辑依赖某类碰撞不存在,地基就危险了。第三,觉得“只用了一半强度”说明长度白给:正因强度减半,工程上才要按目标安全等级反推输出长度——安全文档里的每一个位数,都不是凭感觉留的。

风险提示:本文为密码学机制科普,不构成投资建议;密码算法的强度评估随研究演进,涉及具体实现时请以当期标准为准。