SHA-3 (Keccak):密码学哈希的新一代标准
什么是 SHA-3?
SHA-3 是 NIST 在 2015 年正式发布的第三代安全哈希标准,背后真正的算法名字叫 Keccak(读作 “ketchak”)。它的诞生过程相当有意思——不是 NSA 关起门来设计的,而是通过一场公开的国际竞赛选出来的。
2007 年,NIST 发起 SHA-3 竞赛。背景是 SHA-1 被证明不再安全,SHA-2 虽然还扛得住,但它和 SHA-1 的内部结构一模一样(都是 Merkle-Damgard),万一哪天真从结构层面被突破,整个 SHA 家族就没有备用方案了。换句话说,SHA-3 从一开始就不是来取代 SHA-2 的,它是来当”备胎”的——一个结构完全不同、随时可以顶上来的替代方案。
竞赛持续了五年,全球密码学团队提交了 64 个候选算法。经过三轮淘汰,最终在 2012 年,Guido Bertoni、Joan Daemen(对,也是 AES 的设计者之一)、Michael Peeters 和 Gilles Van Assche 设计的 Keccak 胜出。我读过当年的竞赛报告,评委们选 Keccak 的最核心理由就一条:海绵结构与 Merkle-Damgard 完全不同,攻击 SHA-2 的技术路径对它天然无效。
海绵结构:SHA-3 的核心创新
要理解 SHA-3,必须先扔掉 SHA-2 那套”逐块压缩”的思维模型。SHA-3 用的是一种叫 海绵结构(Sponge Construction) 的东西。
把海绵结构想象成一块真的海绵。你往海绵上倒水(吸收阶段),水渗透到海绵内部的每一个孔隙里;然后你用力挤海绵(挤出阶段),水又流出来了。SHA-3 的过程几乎一模一样:
- 吸收阶段:输入消息被切成小块,一块一块地”吸”进一个很大的内部状态数组里。每吸一块,就和当前状态做 XOR,然后对整个状态执行一轮置换函数
f。 - 挤出阶段:消息全部吸收完后,从状态数组中一块一块地”挤”出哈希值。挤完一块不满意?继续对状态做置换,再挤一块。想挤多长就挤多长。
这个设计的高明之处在于:吸收和挤出共享同一个核心置换函数,输出长度可以根据需要任意调整(所谓的”可扩展输出”XOF)。而 SHA-2 的输出长度是固定的——参数一开始就钉死了。
我记得第一次看 Keccak 的置换函数代码时,注意到的第一件事是它根本不用 SHA-2 那些 Ch、Maj 逻辑函数。Keccak 的 f 置换只用了三种按位操作:XOR、AND、NOT——纯粹的布尔运算,外加一个叫 ι(iota)的常数异或步骤。实现起来出奇地简洁,硬件上尤其省电省面积。
内部状态:一个 5x5x64 的三维比特数组
SHA-3 的内部状态不是一维的,而是一个 5x5 的平面,每个格子存一个 64 位字,总共 1600 位。置换函数 f 在这 1600 位上反复执行 24 轮,每轮包含五个子步骤:
- θ (Theta):把相邻列的信息扩散开来
- ρ (Rho):每个位按不同偏移量循环移位
- π (Pi):重新排列字的位置
- χ (Chi):非线性混合——这是唯一的非线性部分
- ι (Iota):注入轮常数,打破对称性
五个步骤交替执行,经过 24 轮后,哪怕输入消息变了一个比特,整个 1600 位的内部状态都被搅得面目全非。
核心特性
| 特性 | 说明 |
|---|---|
| 输出长度 | 224 / 256 / 384 / 512 位(固定)+ 任意长度(XOF 模式) |
| 内部状态 | 1600 位(5x5x64 三维布局) |
| 轮数 | 24 轮(置换函数 f) |
| 结构 | 海绵结构(Sponge Construction) |
| 抗长度扩展 | 天然免疫——不需要 HMAC 那套额外保护 |
| 抗量子性 | 256 位安全性,Grover 算法降至 128 位(与 SHA-256 相同) |
| 标准化 | FIPS PUB 202 |
最值得单独拎出来说的是 抗长度扩展攻击。SHA-2 系列的 Merkle-Damgard 结构有个天生的弱点:如果你知道 H(M) 和消息 M 的长度,就能算出 H(M || padding || extra),即使你完全不知道 M 是什么。HMAC 之所以要把密钥包两层哈希,就是为了堵这个洞。SHA-3 根本不需要这层防护——海绵结构的”挤出”方式决定了消息全部吸收完之后才输出,攻击者没法在中间截断状态继续拼接。这是结构层面的优势,不是安全参数的比拼。
实际应用场景
1. 后量子密码的底层组件
正在标准化的 NIST 后量子签名算法(比如 CRYSTALS-Dilithium 和 SPHINCS+),很多直接拿 SHA-3 或它的衍生函数 SHAKE 做内部哈希。SHA-3 的简洁布尔结构在零知识证明电路里也很受欢迎——不需要模拟复杂的算术运算,证明生成快不少。
2. Ethereum 生态
以太坊的 Keccak-256(注意不是标准 SHA-3-256——Ethereum 用的是竞赛版的 Keccak,padding 规则有一点点不同)几乎渗透到了每一层:地址生成、交易签名、存储槽计算、Solidity 里 keccak256() 函数。有一次我在测试网部署合约,本地算出的 selector 和 Etherscan 上对不上,排查了很久才发现 Solidity 用的 keccak256 和我们工具里的标准 SHA-3-256 差了一个 padding 位。
3. SHAKE 可扩展输出
SHA-3 标准还定义了 SHAKE128 和 SHAKE256,本质上是一个基于海绵结构的伪随机数流。你可以把它当哈希用,也可以让它输出 64 字节、128 字节甚至更长——这在密钥派生和掩码生成等场景里特别实用。SHA-2 没有这个能力。
4. 硬件受限环境
SHA-3 的 AND-NOT-XOR 操作在 ASIC 和 FPGA 上可以做到极简门电路。同样的安全级别,SHA-3 的硬件实现往往比 SHA-2 更小更省电。IoT 设备和传感器节点的轻量级完整性校验很适合用它。
常见误区
误区一:SHA-3 已经取代了 SHA-2
没有。而且短期内也不会。整个行业的证书体系、协议栈、硬件加速全都绑在 SHA-256 上,迁移成本是天文数字。NIST 自己都说了,SHA-3 是”alternative”而非”replacement”——当备胎用的。只有等 SHA-2 真出了问题,或者用在 SHA-2 不适合的新场景里(比如 XOF),SHA-3 才会站到前台。
误区二:SHA-3 比 SHA-2 慢,所以没什么用
软件实现上 SHA-3 确实普遍比 SHA-256 慢,这在 x86 平台上尤其明显——因为 CPU 里有 SHA-256 的专用指令(Intel SHA Extensions),但没有 SHA-3 的硬件加速。但这不代表 SHA-3 设计得差:它的优势在硬件实现和安全性分析上,软件性能只是权衡的一部分,不是设计目标。
误区三:Keccak 和 SHA-3 是一回事
不完全。Keccak 是算法名,SHA-3 是 NIST 标准化后的版本。两者 padding 不同——标准的 SHA-3 在消息末尾加了 01 两位,而原始的 Keccak 竞赛版只加了一个 1 位。这看起来微不足道,但造成的结果是:同样的输入,SHA-3-256 和 Keccak-256(以太坊用的)输出完全不同。
SHA-3 vs SHA-2 vs BLAKE3
| SHA-2 (SHA-256) | SHA-3 (Keccak) | BLAKE3 | |
|---|---|---|---|
| 结构 | Merkle-Damgard | 海绵结构 | 树状哈希 + Bao 模式 |
| 抗长度扩展 | 需 HMAC 辅助 | 天然免疫 | 天然免疫 |
| 软件速度 | 快(有硬件加速) | 较慢 | 极快 |
| 硬件实现 | 较大 | 更小更省电 | 较大 |
| 可扩展输出 | 否 | 是(SHAKE) | 是 |
| 标准化 | FIPS 180-4 | FIPS 202 | 无(开源社区) |
| 生态地位 | 绝对主流 | 备用 + 特定领域 | 新兴,快速增长 |
BLAKE3 是另一个来自 SHA-3 竞赛家族的后代——BLAKE 当年进了决赛但没赢,它的后代 BLAKE3 在 2020 年发布后因为极快的软件速度获得了不少关注。但 BLAKE3 没有 NIST 背书,在一些合规场景里没法用。SHA-3 的优势恰恰在于它是官方的、被广泛审计的、有 FIPS 认证的。
常见问题
Q: 我应该在新项目里选 SHA-2 还是 SHA-3?
大概率还是 SHA-256。除非你有以下需求:需要 XOF(可扩展输出)、在纯硬件上跑、或者需要天然抗长度扩展攻击。目前的工程现实是 SHA-256 生态完善、加速指令成熟、各种语言都有优化实现。SHA-3 更像一道安全保险——你的项目不需要它,但密码学作为一个整体需要它。
Q: SHA-3 和 SHA-1/SHA-2 有血缘关系吗?
零。名字里的 “SHA” 是 NIST 的标准前缀,不是算法家族标识。SHA-1 和 SHA-2 内部结构一脉相承,SHA-3 是完全从零设计的,连设计团队都完全不同。这就是它被选中的意义——不和前辈共享任何结构弱点。
Q: Grover 算法对 SHA-3 的影响有多大?
和 SHA-256 一样:256 位的抗碰撞安全性在量子攻击下降为 128 位。所以 SHA-3-512 的抗量子安全性实际上是 256 位。这是所有对称密码学(哈希、对称加密)共同面临的情况,不是 SHA-3 的特有问题。非对称密码学(RSA、ECC)才是量子计算机真正能一击致命的领域。
Q: 海绵结构的 “capacity” 是什么,为什么重要?
海绵结构把 1600 位内部状态分成两部分:rate(速率区) 用于读写数据,capacity(容量区) 永不直接接触输入或输出。安全检查的核心就在 capacity——它越大,找到碰撞或原像的计算量就越大。SHA-3-256 的 capacity 是 512 位,这让任意输出长度的抗碰撞强度都至少是 128 位。这个设计的巧妙之处在于:安全边界是结构的一部分,不需要在输出阶段额外做什么。
Q: HMAC-SHA3 还有必要吗?
技术上没必要——SHA-3 天然免疫长度扩展攻击,直接用 SHA-3(key || message) 就够安全。NIST 甚至专门出了 SP 800-185 定义 SHA-3 的原生认证模式 KMAC,完全不用 HMAC 那套双重哈希的套路。但向后兼容的理由仍然存在:如果你现有的协议栈已经围绕 HMAC 抽象构建好了,HMAC-SHA3 照样能用,没啥问题。