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-224 | 224 位 | 32 位 | 64 轮 | 与 P-224 等配合的签名哈希 |
| SHA-256 | 256 位 | 32 位 | 64 轮 | 证书、签名、HMAC、文件校验 |
| SHA-384 | 384 位 | 64 位 | 80 轮 | P-384 场景与部分 TLS 套件 |
| SHA-512 | 512 位 | 64 位 | 80 轮 | 64 位平台、HMAC、Ed25519 内部哈希 |
| SHA-512/256 | 256 位 | 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 位。所以「位数越大越慢」并不成立,选择时以协议要求和实测吞吐为准。