直觉上,输出更长、轮数更多的算法应该更慢。SHA-512 的输出是 512 位,轮数是 80 轮,而 SHA-256 只有 256 位、64 轮。按这个逻辑,SHA-512 应该慢不少。但在 64 位平台上实测的结果往往相反——SHA-512 反而更快。这个反直觉的现象,根源在于「字长」。
字长决定了运算效率
哈希算法内部是一系列按位运算:异或、与、循环移位、加法。这些运算作用在「字」上,而字的宽度由算法定义。
SHA-256 使用 32 位字,SHA-512 使用 64 位字。
现代服务器和桌面 CPU 基本都是 64 位的,一次能处理 64 位数据。当算法需要按 32 位字运算时,CPU 的 64 位能力只用到了一半;而 SHA-512 的 64 位字运算能完整利用寄存器宽度。这就抵消了 SHA-512 轮数更多带来的开销。
还有一个因素:分组大小。SHA-256 一次处理 512 位数据,SHA-512 一次处理 1024 位。处理大文件时,SHA-512 每次能「吃」进更多数据,虽然每轮更复杂,但单位数据的总轮数更少。
什么时候 SHA-256 更快
上面说的是 64 位平台的情况。在 32 位嵌入式环境里,结论会反转。
32 位 CPU 处理 64 位字需要拆成两条指令,SHA-512 的每次运算都要多花一倍时间。此时 SHA-256 明显更快,而且内存占用也更小,适合资源受限的设备。
另一个影响因素是硬件指令。主流 CPU 提供了 SHA 扩展指令,但不同架构支持的范围不同。有些实现只为 SHA-256 提供加速,有些同时支持 SHA-1 和 SHA-256,SHA-512 的硬件加速支持相对少一些。当底层启用了硬件指令时,软件实现层面的字长优势就不那么重要了——这时候实际性能取决于具体平台。
所以「谁更快」没有唯一答案,需要按目标平台实测。这也是为什么性能敏感的场景不应该凭直觉选算法。
截断变体解决的是长度问题
如果既想要 SHA-512 在 64 位平台上的性能,又不需要 512 位的输出长度,FIPS 180-4 提供了两个截断变体:SHA-512/256 和 SHA-512/224。
它们输出 256 位和 224 位,但不是简单地把 SHA-512 的结果截掉一半。它们使用不同的初始向量,因此算出的结果与 SHA-512 的前半部分不同,也与 SHA-256 完全不同。
这个设计有实际意义。简单截断会让攻击者知道被丢弃的部分,理论上可能影响安全边界;而使用独立初始向量的变体在安全分析上更清晰。所以如果你的需求是「256 位输出 + 64 位平台性能」,正确的选择是 SHA-512/256,而不是「算 SHA-512 再截断」。
选型时的判断顺序
实际项目里,建议按这个顺序判断。
首先看合规与互通要求。如果对接方或标准规定必须用某个算法,就没有选择余地。
其次看输出长度需求。需要 256 位输出就用 SHA-256 或 SHA-512/256;需要 512 位输出才用 SHA-512。多数场景 256 位已经远超需求。
最后看目标平台。64 位服务端可以在 SHA-256 与 SHA-512 之间按实测性能选;32 位嵌入式设备优先 SHA-256。
还有一点要提醒:所有这些讨论都只针对通用哈希的选型。如果目的是口令存储,SHA-256 和 SHA-512 都不适用,应该用 Bcrypt、Argon2 或 PBKDF2。
检查清单
- SHA-512 用 64 位字运算,在 64 位 CPU 上往往比 SHA-256 更快
- SHA-512 的分组是 1024 位,处理大文件时单位数据轮数更少
- 32 位嵌入式环境下 SHA-256 更快,因为 64 位运算要拆成多条指令
- 硬件 SHA 指令的支持范围会影响实际性能,选型时应实测
- 需要 256 位输出又要 64 位性能时,用 SHA-512/256 而不是截断 SHA-512
- 口令存储不使用 SHA 系列,应选慢哈希