首页/安全/加密与证书速查/SHA-2 家族(SHA-224/256/384/512)
加密算法基础95 条

SHA-2 家族(SHA-224/256/384/512)

FIPS 180-4 定义的哈希家族,包含 SHA-224、SHA-256、SHA-384、SHA-512 与截断变体;结构基于 Merkle–Damgård 迭代,是当前使用最广的密码学哈希。

加密与证书速查安全更新于 2026-10-13

SHA-2 是什么

SHA-2 是 FIPS 180-4 定义的哈希家族,成员包括 SHA-224、SHA-256、SHA-384、SHA-512 以及 SHA-512/224、SHA-512/256 等截断变体。前四者的区别在于输出长度、内部字宽与轮数:SHA-224/256 用 32 位字、64 轮,SHA-384/512 用 64 位字、80 轮。结构上都是 Merkle-Damgard 迭代,是目前使用最广泛的密码学哈希。

基本信息

标准FIPS 180-4
输出长度224 / 256 / 384 / 512 位
字宽32 位(224、256);64 位(384、512)
轮数64 轮(32 位字);80 轮(64 位字)
结构Merkle-Damgard 迭代 + 长度填充
选用原则安全强度不低于所配公钥与协议的强度
常见实现openssl dgst、sha256sum/sha512sum、语言标准库

典型使用场景

  • 证书与签名:按 CA 与协议要求选择 SHA-256 或 SHA-384 作为签名摘要
  • TLS 套件与密钥派生:1.3 的三个套件分别绑定 SHA-256 或 SHA-384
  • HMAC 与接口签名:HMAC-SHA256 是开放平台默认方案
  • 文件与固件校验:sha256sum/sha512sum 生成清单
  • 口令派生:PBKDF2-HMAC-SHA256/SHA-512 的内部哈希
  • 标识与去重:以摘要作为唯一键或分片键

成员对照

算法摘要长度字长轮数典型用途
SHA-224224 位32 位64 轮与 P-224 等配合的签名哈希
SHA-256256 位32 位64 轮证书、签名、HMAC、文件校验
SHA-384384 位64 位80 轮P-384 场景与部分 TLS 套件
SHA-512512 位64 位80 轮64 位平台、HMAC、Ed25519 内部哈希
SHA-512/256256 位64 位80 轮需要短输出但偏好 64 位结构时使用

常用命令与测试向量

常用命令与测试向量
# 标准测试向量:输入 abc 的 SHA-256 结果固定,可用于自检实现
printf '%s' abc | openssl dgst -sha256
# 输出应为 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
# 不同成员用同一输入对比,确认长度与实现一致
printf '%s' abc | openssl dgst -sha384
printf '%s' abc | openssl dgst -sha512
# 文件校验(大文件流式计算,不占内存)
sha256sum file.bin
sha512sum file.bin
# 输出二进制摘要并转 Base64,便于放进 JSON 或 Header
openssl dgst -sha256 -binary file.bin | openssl base64
选择哈希的原则是「强度匹配用途」:普通签名与 TLS 用 SHA-256 即可;与 P-384 等更高强度公钥搭配时用 SHA-384;64 位平台上 SHA-512 在大文件场景可能反而更快。不要为了「更强」把哈希长度堆到远高于公钥强度。
SHA-224 与 SHA-256 的初始向量不同,不能通过简单截断互换;SHA-512/256 也不是 SHA-256 的截断版本。跨系统对接时如果一方按截断实现、另一方按标准实现,会得到完全不同的摘要,且报错信息通常只写「校验失败」。
SHA-2 家族目前没有实用的碰撞攻击。真正需要担心的不是算法本身,而是使用方式:用哈希代替签名做来源校验、用单轮哈希存口令、或在协议里把哈希当作密钥派生函数直接使用。

语言接口示例

语言接口示例
import hashlib, hmac
# 流式喂入,适合大文件或网络流,避免整块读入内存
h = hashlib.new('sha256')
h.update(b'chunk-1')
h.update(b'chunk-2')
print(h.hexdigest())          # 等价于对两段拼接后一次性计算
# HMAC 直接用标准库,不要自行拼 ipad/opad
print(hmac.new(b'secret', b'message', 'sha256').hexdigest())
# 需要与命令行结果比对时注意:命令行的 echo 会带上换行

对接与迁移要点

  • 在协议与配置里显式写明使用哪个成员,不要笼统写「用 SHA2」
  • 对接前先用官方测试向量互相自检,确认双方实现一致
  • 从 SHA-1 迁移时同步检查证书链、代码签名与时间戳,任一层遗留都会判为不合规
  • 涉及口令或密钥派生时改用 PBKDF2-HMAC-SHA256 或 Argon2id,而不是裸哈希
  • 需要短输出又要 64 位结构时可用 SHA-512/256,但必须与对端明确约定,不能按截断理解
两代结构差异值得留意:SHA-512 使用 1024 位块、80 轮与 64 位字,在 64 位 CPU 上常比 SHA-256 更快;SHA-384 是在 SHA-512 基础上换初值后截断到 384 位。所以「位数越大越慢」并不成立,选择时以协议要求和实测吞吐为准。

易错点

  • 把 SHA-224/SHA-512-256 当作其他成员的截断:初值不同,结果不通用,混用会导致静默的校验失败
  • 按输出长度评估抗碰撞强度:SHA-256 的抗碰撞强度只有约 128 位,签名场景需按此量级评估长期安全性
  • 在同一协议里混用多种成员却未在报文里标明算法:对端无法判断该用哪个,互通时只能靠试
  • 用 SHA-2 直接派生密钥:哈希不是 KDF,缺少盐与工作因子,口令场景必须先经 PBKDF2/Argon2id
  • 忽略实现侧差异:不同库对超长输入、编码与填充的处理细节一致但接口不同,自研实现要用官方测试向量自检

数据来源与参考

  • FIPS 180-4(SHA-2 系列)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌