看到 SHA-3 这个名字,很多人会下意识地认为「数字更大,说明 SHA-2 被淘汰了」。但实际情况恰恰相反:SHA-256 至今没有被攻破,而 SHA-3 也并不是为了替代它而生的。理解这两个标准之间的关系,能帮你在选型时做出正确判断。
SHA-2 家族的构成
SHA-2 并不是一个单一算法,而是一个家族。NIST 在 2001 年发布时包含了几个成员,它们的输出长度不同:
| 算法 | 输出位数 | 字长 | 轮数 |
|---|---|---|---|
| SHA-224 | 224 | 32 位 | 64 |
| SHA-256 | 256 | 32 位 | 64 |
| SHA-384 | 384 | 64 位 | 80 |
| SHA-512 | 512 | 64 位 | 80 |
其中 SHA-256 和 SHA-512 是两种基本结构,区别在字长、分组大小和轮数。SHA-224 是 SHA-256 的截断变体,SHA-384 是 SHA-512 的截断变体。后来 FIPS 180-4 又补充了 SHA-512/224 和 SHA-512/256 两个变体,它们使用不同的初始向量,输出长度与 SHA-224、SHA-256 相同,但结果完全不同。
整个家族采用的都是 Merkle–Damgård 迭代结构,配合 Davies–Meyer 压缩函数。这种结构的特点是:把输入分成固定大小的块,逐块更新一个内部状态,最后输出摘要。
SHA-3 换了一套完全不同的结构
SHA-3 来自 NIST 在 2007 到 2012 年间举办的一场公开竞赛,最终选定的是 Keccak 算法,2015 年发布为 FIPS 202。
它最大的不同在于结构。SHA-3 使用海绵结构(sponge construction),而不是 Merkle–Damgård。它的工作方式可以分成两个阶段:先把输入数据「吸收」进一个内部状态,再把状态「挤出」成输出。这个模型在数学性质上与迭代结构有本质差异。
换结构的意义在于风险分散。Merkle–Damgård 结构有一个众所周知的性质:如果压缩函数存在某种弱点,攻击者可以利用长度扩展等方式扩展攻击。SHA-3 从设计上就不共享这些潜在弱点。
为什么说 SHA-3 不是替代品
如果 SHA-2 被攻破,SHA-3 就是现成的备选方案——这是 NIST 举办竞赛的核心动机之一。竞赛启动的时间点(2007 年)与 SHA-1 出现理论警告(2005 年)高度相关,业界当时担心 SHA-2 也可能步 SHA-1 的后尘。
但十几年过去,SHA-2 依然安全。针对 SHA-1 的那类攻击方法对 SHA-2 不适用,因为 SHA-2 的轮数和消息扩展设计都能抵抗差分攻击。所以 SHA-3 的定位从「替代者」变成了「并行标准」:两者都被认可,都安全,用途各有侧重。
具体来说,SHA-3 更适合这些情况:需要与 SHA-2 结构差异化以分散风险;需要利用海绵结构的可变输出长度特性(SHAKE128、SHAKE256 是 SHA-3 的可扩展输出函数,可以输出任意长度);或者合规要求明确指定 SHA-3。
选型时的实际建议
通用场景直接选 SHA-256。它的兼容性最好——几乎所有的语言标准库、TLS 实现、硬件指令集都支持它,CPU 层面的 SHA 扩展指令还能显著加速。这个生态优势是 SHA-3 目前比不上的。
需要更长输出或 64 位平台的性能时,选 SHA-512。它在 64 位 CPU 上往往比 SHA-256 更快,因为内部按 64 位字运算。
需要可变长度输出时,考虑 SHAKE 系列。例如某些协议需要从一段种子派生出任意长度的密钥材料,海绵结构的可扩展输出天然适合。
如果所在体系(如某些国家的密码标准)明确要求 SHA-3,就按要求使用,不必因为「SHA-256 也安全」而强行替换。
检查清单
- SHA-2 是一个家族,包含 SHA-224、SHA-256、SHA-384、SHA-512 及截断变体
- SHA-2 采用 Merkle–Damgård 结构,SHA-3 采用海绵结构,两者设计完全不同
- SHA-3 是为 SHA-2 万一被攻破而准备的备选标准,不是因为 SHA-2 已被攻破
- SHA-256 目前没有公开的实际碰撞攻击,仍是最主流的完整性算法
- 通用场景选 SHA-256,64 位平台追求吞吐选 SHA-512
- 需要可变长度输出时考虑 SHAKE 系列,它基于海绵结构