SHA-2 哈希函数家族原理详解:从 Merkle-Damgård 结构到安全性证明

算法原理 · 2026-07-19

概述

SHA-2(Secure Hash Algorithm 2)是由美国国家标准与技术研究院(NIST)于 2001 年发布、2012 年在 FIPS 180-4 中标准化的密码学哈希函数家族。它包含六种输出长度不同的变体:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256,是目前全球应用最广泛的哈希算法标准。

SHA-2 的设计是对 SHA-1(FIPS 180-1)安全弱点的直接回应。2005 年王小云团队提出的碰撞攻击证明 SHA-1 的实际安全强度远低于理论值(2⁶¹ 次运算而非 2⁸⁰),NIST 随即推动 SHA-2 作为替代方案。与 SHA-3(Keccak)采用全新的海绵结构不同,SHA-2 延续了经典的 Merkle-Damgård 迭代结构,但在消息扩展和压缩函数层面做了大幅增强。

SHA-2 的关键参数

变体输出长度字长轮数块大小初始值来源
SHA-224224 bit32 bit64512 bitSHA-256 IV 截断
SHA-256256 bit32 bit64512 bit质数平方根小数部分
SHA-384384 bit64 bit641024 bitSHA-512 IV 截断
SHA-512512 bit64 bit641024 bit质数平方根小数部分
:SHA-512/224 和 SHA-512/256 使用与 SHA-512 相同的字长和轮数,但采用不同的初始值(IV),输出截断为 224 和 256 位。

Merkle-Damgård 结构

SHA-2 建立在 Merkle-Damgård 迭代范式之上,这是绝大多数传统哈希函数(MD5、SHA-1、SHA-2、SM3)的通用框架。

迭代范式

Merkle-Damgård 强化

Merkle-Damgård 结构本身并非在任意压缩函数下都是安全的,它满足以下性质:

  • 抗碰撞性传递:若压缩函数抗碰撞,则整个哈希函数抗碰撞
  • 长度编码安全性:最终块中编码消息长度,防止长度扩展攻击(但 SHA-2 实际仍受此问题影响,见"相关实践")

消息扩展(Message Schedule)

SHA-256 将 512-bit 消息块(16 个 32-bit 字)扩展为 64 个字,供后续 64 轮压缩使用:

CODE
W[0..15] = M 的 16 个 32-bit 字(直接复制)

for t = 16 to 63:
    σ₀(x) = ROTR⁷(x) ⊕ ROTR¹⁸(x) ⊕ SHR³(x)
    σ₁(x) = ROTR¹⁷(x) ⊕ ROTR¹⁹(x) ⊕ SHR¹⁰(x)
    W[t] = σ₁(W[t-2]) + W[t-7] + σ₀(W[t-15]) + W[t-16]

SHA-512 使用类似的扩展算法,但轮数为 80 轮,字长 64 bit:

CODE
for t = 16 to 79:
    σ₀(x) = ROTR¹(x) ⊕ ROTR⁸(x) ⊕ SHR⁷(x)
    σ₁(x) = ROTR¹⁹(x) ⊕ ROTR⁶¹(x) ⊕ SHR⁶(x)
    W[t] = σ₁(W[t-2]) + W[t-7] + σ₀(W[t-15]) + W[t-16]
关键设计:消息扩展的非线性引入了雪崩效应——输入消息的微小变化会导致 64 个扩展字完全不同。

压缩函数(Compression Function)

SHA-256 的压缩函数是 64 轮迭代,每轮使用不同的常数 K[t] 和消息字 W[t]:

轮函数结构

轮常数 K[0..63]

SHA-256 的前 64 个质数的立方根小数部分,取前 32 位:

CODE
K[0]  = 0x428a2f98  (2 的立方根)
K[1]  = 0x71374491  (3 的立方根)
K[2]  = 0xb5c0fbcf  (5 的立方根)
K[3]  = 0xe9b5dba5  (7 的立方根)
...
K[63] = 0xc67178f2  (311 的立方根)

SHA-512 使用 64 位字长,轮常数为前 80 个质数的立方根小数部分的前 64 位。

初始值 IV

SHA-256 的初始值来自前 8 个质数的平方根小数部分的前 32 位:

CODE
H[0] = 0x6a09e667  (√2)
H[1] = 0xbb67ae85  (√3)
H[2] = 0x3c6ef372  (√5)
H[3] = 0xa54ff53a  (√7)
H[4] = 0x510e527f  (√11)
H[5] = 0x9b05688c  (√13)
H[6] = 0x1f83d9ab  (√17)
H[7] = 0x5be0cd19  (√19)
设计哲学:使用数学常数(质数平方根/立方根)作为"nothing up my sleeve numbers",避免隐藏后门嫌疑。

安全性分析

抗碰撞性

SHA-256 的理论抗碰撞强度为 2¹²⁸(生日攻击边界),SHA-512 为 2²⁵⁶。截至 2026 年,对完整轮数的 SHA-256 尚未找到低于理论值的碰撞攻击。

已知攻击

攻击类型目标复杂度状态
碰撞攻击完整 SHA-2562¹²⁸理论最优
碰撞攻击24 轮简化版2¹¹²学术研究
预像攻击完整 SHA-2562²⁵⁶理论最优
多碰撞攻击完整轮2¹²⁸ + k·2⁶⁴Joux 2004
长度扩展攻击SHA-256已知技术可行实际风险

长度扩展攻击

SHA-256 作为纯 Merkle-Damgård 结构,天然存在长度扩展攻击:已知 H(m) = h,攻击者可以构造 H(m || pad || m') 而无需知道 m。这会影响某些直接使用哈希构造 MAC 的方案(如 HMAC(secret, msg) 是安全构造,但 H(secret || msg) 不安全)。

SHA-2 vs 国密 SM3 对比

SM3 是中国国家密码管理局发布的密码杂凑算法标准(GM/T 0004-2012),与 SHA-256 同为 256-bit 输出,但结构设计有重要差异。

结构对比

维度SHA-256SM3
迭代结构Merkle-DamgårdMerkle-Damgård
字长32 bit32 bit
轮数64 轮64 轮
消息扩展非线性扩展(σ₀, σ₁)线性+非线性混合(异或+循环移位)
压缩函数8 变量迭代,Ch/Maj 布尔函数3 变量迭代,异或/与/或混合
消息块大小512 bit512 bit
初始值来源质数平方根固定常数
标准化NIST FIPS 180-4GM/T 0004-2012

SM3 消息扩展特点

CODE
W[0..15] = M 的 16 个字
for j = 16 to 67:
    W[j] = P₁(W[j-16] ⊕ W[j-9] ⊕ ROTL³(W[j-3])) ⊕ ROTL¹⁵(W[j-13]) ⊕ W[j-6]

W'[j] = W[j] ⊕ W[j+4]   (用于轮函数)

SM3 的消息扩展比 SHA-256 更强地混合了非线性(P₁ 置换)和线性(异或+移位)操作。

SM3 压缩函数

CODE
ABCDEFGH ← Vᵢ₋₁
for j = 0 to 16:
    SS₁ = ROTL¹²((ROTL¹²(A) + E + ROTLʲ(Tⱼ))
    SS₂ = SS₁ ⊕ ROTL¹²(A)
    TT₁ = FFⱼ(A,B,C) + D + SS₂ + W'[j]
    TT₂ = GGⱼ(E,F,G) + H + SS₁ + W[j]
    D=C, C=ROTL⁹(B), B=A, A=TT₁
    G=F, F=ROTL¹⁹(E), E=P₀(TT₂), H=TT₂
for j = 17 to 63:
    (结构相同;区别在于 FFⱼ/GGⱼ 切换为第二组布尔函数)
    (FF₀..₁₆ 用 XOR,FF₁₇..₆₃ 用 AND-OR 混合;GG 同理)
Vᵢ = ABCDEFGH ⊕ Vᵢ₋₁
关键差异:SM3 使用 64 轮迭代(SHA-256 也是 64 轮),但每轮使用两个独立的变量更新路径(SS 和 TT),增加了并行分析的难度。

安全强度对比

安全属性SHA-256SM3说明
抗碰撞2¹²⁸2¹²⁸理论值相同
抗原像2²⁵⁶2²⁵⁶理论值相同
实际碰撞攻击无有效攻击无有效攻击2026 年现状
长度扩展存在存在两者均受 Merkle-Damgård 结构影响

工程实现要点

Python 标准库调用

HMAC-SHA256(安全的 MAC 构造)

PYTHON
import hmac
import hashlib
import os

# HMAC 是长度扩展攻击的安全防护
secret_key = os.urandom(32)
message = b"authenticated data"
mac = hmac.new(secret_key, message, hashlib.sha256).digest()
print(f"HMAC-SHA256: {mac.hex()}")

标准引用

标准编号名称说明
NIST FIPS 180-4Secure Hash Standard (SHS)SHA-2 主标准
NIST FIPS 202SHA-3 StandardSHA-3 补充
GM/T 0004-2012SM3 密码杂凑算法国密杂凑标准
RFC 6234US Secure Hash Algorithms实现参考

相关实践


参考来源

  • NIST FIPS 180-4: Secure Hash Standard (SHS)
  • NIST SP 800-107 Rev.1: Recommendation for Using Approved Hash Algorithms
  • GM/T 0004-2012: SM3 密码杂凑算法
  • RFC 6234: US Secure Hash Algorithms (SHA and SHAHMAC)