Keccak、SHA-256 与 SHA-3:同一个名字为什么会算出两种哈希 图 1
Keccak、SHA-256 与 SHA-3:同一个名字为什么会算出两种哈希 · 图 1

写智能合约的工具函数、查哈希校验工具、翻旧代码里的注释,你会撞上一个命名混乱的三角:SHA-256、Keccak-256、SHA-3。它们都输出几百位的摘要值,名字又像亲戚,但以太坊生态实际用的是 Keccak,以太坊的 RPC 却常把它标成 SHA3。这个历史误会有真实代价:跨链做哈希一致性核对时,用错函数会得到完全不同的结果,让人误以为数据被篡改。本文把三者关系一次理清。

同一场竞赛的两代结果

故事的起点是 2006 年前后意大利密码学家团队设计的哈希算法族 Keccak。NIST 为取代逐渐显露弱点的 SHA-2 系列发起 SHA-3 征集竞赛,Keccak 在公开竞争中胜出。但标准化不是原样照抄:2015 年发布的 FIPS 202 在 Keccak 基础上做了一处关键调整——在填充规则末尾增加了域分隔比特。改动很小,安全性论证更强,却造成一个工程后果:同一输入下,SHA3-256 与原始 Keccak-256 的输出完全不同。名字撞了,函数不通用。

Keccak、SHA-256 与 SHA-3:同一个名字为什么会算出两种哈希 图 2
Keccak、SHA-256 与 SHA-3:同一个名字为什么会算出两种哈希 · 图 2

以太坊为什么停在 Keccak

以太坊的开发早于 SHA-3 定稿,实现时选用了原始 Keccak-256,后来为了兼容性没有跟随改名。于是留下几处”口是心非”:虚拟机里那条负责哈希的核心指令在规范里就叫 SHA3,执行的却是原始 Keccak;早期 JSON-RPC 里有个方法叫 web3_sha3,算的同样不是标准 SHA3;开发者工具里 keccak256 与 sha3 两种写法指向同一算法是常态,而在线哈希计算器默认算的多是标准 SHA3。判断标准只有一个:看工具实际标注的算法参数,不看函数名。

和比特币的 SHA-256 是什么关系

完全不同的家族。比特币用的 SHA-256 属于 SHA-2 系列,采用不同的内部结构;以太坊的 Keccak 使用海绵结构。两者都是当前公认安全的抗碰撞哈希,长度也一样是 256 位,但互不能替代:把比特币脚本里的运算结果拿到 EVM 里复算,对不上是正常现象,真正的 bug 反而在于”以为能对上”。链与链之间做承诺校验、跨链证明、签名域复现时,第一步永远是确认两边用的是哪个函数。

动手核验的最短路径

不需要背概念,做个实验就懂:找任意一段公开文本,分别用可靠的 keccak 工具与标准 SHA3 工具计算同一输入,你会得到两个不相干的摘要,从此记住这对”同名不同人”。以太坊的空输入 Keccak-256 值是公开可查的固定串,用它做工具自检最方便。再往前一层:审合约代码时,注意有些标准库把 SHA3 函数名映射到的恰恰是 Keccak 实现,重命名不等于改算法。哈希没有好坏之分,用错才有。

风险提示:本文为技术事实说明,不涉及任何资产价值判断,不构成投资建议。

NIST 为什么偏要改那一小段填充

标准化时的改动不是审美问题。原始 Keccak 在通用场景中直接复用,存在域混用的隐患:同一种海绵结构若被不同协议以不同方式调用,一类被称为”使用错位”的攻击面会放大。FIPS 202 在填充尾部加入域分隔比特,等于给每个输出函数贴上专属指纹,同一输入下各函数从此互不兼容,安全性论证也得以针对每个函数单独成立。代价就是以太坊生态今天的历史包袱:先上线的链没改,后定稿的标准不同名同实不同。记住这个事实本身,能帮你解释为什么同一句文本在两个工具里会算出两个完全不同的摘要。

真实事故画像:哈希对不上时先查函数名

跨链桥、链上签名校验、工具脚本复算这三类场景最容易翻车。典型症状是:签名原文、序列化方式都没错,最终摘要却完全不同。排查顺序应当是:先确认双方工具实际调用的函数(SHA3 还是 Keccak),再核对输入编码,最后才怀疑数据。大量”哈希异常”工单查到最后,是有人把标准 SHA3 工具的输出拿去和以太坊签名结果比对。函数名撞车的历史遗留,值得每个写校验逻辑的人主动写进文档。