SM4 分组密码算法原理详解:从设计思想到安全分析
title: "SM4 分组密码算法原理详解:从设计思想到安全分析" slug: "sm4-algorithm" excerpt: "SM4 是中国国家密码管理局发布的分组密码算法(GB/T 32907-2016),采用 32 轮非平衡 Feistel 结构,分组和密钥长度均为 128 比特。本文从算法结构、S 盒设计准则、合成置换 T、密钥扩展算法、差分/线性密码分析到与 AES 的全方位对比,系统讲解 SM4 的核心原理与设计取舍。" category: algorithm tags: - SM4 - 分组密码 - Feistel - S盒 - 国密
概述
SM4(原名 SMS4)是中国国家密码管理局于 2006 年发布的商业密码算法,2012 年公开发布,2016 年升级为国家标准 GB/T 32907-2016。该算法设计由中国科学院数据安全与通信保密研究中心(原国家密码管理局商用密码研究中心)主导,主要设计者为吕述望团队。
SM4 的定位很明确:作为 AES 的国产替代方案,用于金融、政务、关键信息基础设施等场景的对称加密。它的核心参数——128 比特分组、128 比特密钥、32 轮迭代——反映了一种与 AES 截然不同的设计哲学:不追求最少的轮数,而是通过更多的轮数和更简单的轮函数来实现可证明的安全性。
在国际标准化方面,SM4 已通过 IETF CFRG 发布为 informational draft(draft-ribose-cfrg-sm4-04),并逐步被纳入 ISO/IEC 标准体系。
算法基本参数
| 参数 | SM4 | AES-128 | 说明 |
|---|---|---|---|
| 标准编号 | GB/T 32907-2016 | NIST FIPS 197 | SM4 于 2006 年公开算法 |
| 分组长度 | 128 bit | 128 bit | 相同的分组大小 |
| 密钥长度 | 128 bit | 128/192/256 bit | SM4 仅支持 128-bit 密钥 |
| 轮数 | 32 | 10/12/14 | SM4 轮数远多于 AES |
| 结构类型 | 非平衡 Feistel | SPN(替换-置换网络) | 根本性的结构差异 |
| 状态表示 | 4 个 32-bit 字 | 4×4 字节矩阵 | 位宽不同 |
| S 盒 | 8→8 bit(256 字节) | 8→8 bit(256 字节) | 大小相同,构造方法不同 |
| 设计公开时间 | 2006 年 | 1998 年 | AES 早 8 年 |
算法结构:非平衡 Feistel 网络
为什么选择 Feistel 而非 SPN?
分组密码的两大主流结构是 SPN(Substitution-Permutation Network,如 AES)和 Feistel 网络(如 DES、Blowfish)。两者的核心区别在于:
- SPN:每一轮都对整个状态同时做替换(S 盒)和置换(线性层)。扩散速度快(AES 只需 10 轮),但加密和解密的电路不同——解密需要逆 S 盒和逆 MixColumns。
- Feistel:每一轮只更新状态的一半(将状态分为左右两半,只变换另一半)。扩散较慢,但加解密结构几乎相同——只需将轮密钥倒序使用。
- 加解密复用:加密和解密使用同一套硬件逻辑,仅轮密钥顺序相反
- 硬件友好:轮函数只操作 32-bit 字,不需要处理完整的 128-bit 状态
- 软件高效:32-bit 字操作与 32/64 位 CPU 天然对齐
加密流程
SM4 的加密过程可以描述为:
输入: 明文 P = (X0, X1, X2, X3) // 4 个 32-bit 字,共 128 bit
对于 i = 0, 1, ..., 31:
X_{i+4} = X0 ⊕ T(X1 ⊕ X2 ⊕ X3 ⊕ rk_i)
// 状态左移: (X0, X1, X2, X3) ← (X1, X2, X3, X_{i+4})
输出: 密文 C = (X35, X34, X33, X32) // 注意最终逆序用流程图表示:
SM4 单轮结构
┌─────────────────────────────────────────────┐
│ │
│ X0 ─────────────┐ │
│ │ │
│ X1 ──┐ ▼ │
│ │ ┌──────────┐ │
│ X2 ──┼───►│ ⊕ rk_i │ │
│ │ └────┬─────┘ │
│ X3 ──┘ │ │
│ ▼ │
│ ┌───────────┐ │
│ │ T 变换 │ │
│ │ T = L ◦ τ │ │
│ └─────┬─────┘ │
│ │ │
│ ▼ │
│ ┌───────────┐ │
│ │ ⊕ X0 │──► X4 (新字) │
│ └───────────┘ │
│ │
│ 状态更新: (X0,X1,X2,X3) → (X1,X2,X3,X4) │
└─────────────────────────────────────────────┘解密:为什么只需倒序轮密钥?
Feistel 网络的一个关键性质是:解密不需要"逆轮函数",只需将轮密钥倒序使用。这是因为每一轮的变换可以表示为:
X_{i+4} = X0 ⊕ T(X1 ⊕ X2 ⊕ X3 ⊕ rk_i)在解密时,已知 (X1, X2, X3, X4),要恢复 X0:
X0 = X4 ⊕ T(X1 ⊕ X2 ⊕ X3 ⊕ rk_i)这与加密的轮函数形式完全相同!解密过程为:
对于 i = 31, 30, ..., 0:
X_i = X_{i+4} ⊕ T(X_{i+1} ⊕ X_{i+2} ⊕ X_{i+3} ⊕ rk_i)这意味着硬件实现中,加密和解密可以共享同一个轮函数电路,只需要一个多路选择器来决定轮密钥的使用顺序。
S 盒设计:合成置换与代数透明度
S 盒的角色
S 盒(Substitution Box)是分组密码中唯一的非线性组件。如果去掉 S 盒,整个加密就退化为一个线性变换——攻击者只需收集少量明文-密文对,就能通过高斯消元法求出密钥。
S 盒的安全指标:
| 指标 | 含义 | AES S 盒 | SM4 S 盒 |
|---|---|---|---|
| 差分均匀度 δ | 抵抗差分攻击的能力,越小越好 | 4 | 4 |
| 线性逼近度 λ | 抵抗线性攻击的能力,越小越好 | 16 | 16 |
| 非线性度 | 与所有线性函数的最小距离 | 112 | 112 |
| 代数次数 | 代数表达式的最高次数 | 7 | 7 |
| 不动点数 | S(x)=x 的输入个数 | 0 | 0 |
AES S 盒的代数构造
AES 的 S 盒构造过程完全公开,分为两步:
步骤 1: 在 GF(2^8) 上求乘法逆元
将输入字节视为 GF(2^8) 中的元素(不可约多项式 x^8+x^4+x^3+x+1)
输出 = a^(-1)(0 映射到 0)
步骤 2: GF(2) 上的仿射变换
输出 = M · 输入 ⊕ 0x63
M 是一个 8×8 的二进制矩阵这种"先求逆、后仿射"的结构被称为 Wide Trail Strategy 的一部分,其优势在于:
- 差分均匀度有数学证明(上界为 4)
- 代数结构清晰,便于分析抵抗代数攻击(XSL attack)的能力
- 满足 nothing-up-my-sleeve 原则——构造过程完全透明
SM4 S 盒:合成置换方法
SM4 的 S 盒设计方法未完全公开。标准文档(GB/T 32907-2016)直接给出了完整的 256 字节查找表,但未说明构造过程。学术界通过逆向分析发现:
SM4_SBOX(x) = A2 · AES_SBOX(A1 · x ⊕ c1) ⊕ c2即 SM4 的 S 盒可以表示为:输入仿射变换 → AES S 盒(GF(2^8) 求逆 + 仿射)→ 输出仿射变换。这种方法在学术上称为 composite field(合成域)或 tower field 构造。
这种设计选择的含义:
- 安全性继承:SM4 S 盒的安全指标与 AES S 盒相同,因为它本质上是 AES S 盒的仿射等价变换
- 实现复用:在支持 AES-NI 的 x86 处理器上,可以利用
AESENCLAST指令高效计算 SM4 的 S 盒 - 透明度争议:构造过程不完全公开,不满足严格的 nothing-up-my-sleeve 原则——虽然最终结果的安全指标可验证,但"为什么选这两个仿射变换"的问题没有完全回答
nothing-up-my-sleeve 原则:密码算法的设计过程必须完全透明,使用的常数必须有可验证的来源(如自然对数的小数部分),以防止设计者在参数中植入后门。
轮函数 T 变换:非线性 + 线性两步走
SM4 的轮函数核心是 T 变换,它是一个合成变换 T = L ◦ τ(先做非线性 τ,再做线性 L)。
第一步:非线性变换 τ
输入: 32-bit 字 A = (a3, a2, a1, a0) // 4 个字节
输出: B = (SBOX[a3], SBOX[a2], SBOX[a1], SBOX[a0])即将 32-bit 字的 4 个字节分别独立查 S 盒。这是 SM4 中唯一的非线性操作。
第二步:线性变换 L
输入: 32-bit 字 B
输出: C = B ⊕ ROL(B,2) ⊕ ROL(B,10) ⊕ ROL(B,18) ⊕ ROL(B,24)其中 ROL(B,n) 表示 32-bit 循环左移 n 位。
L 变换的设计目标是扩散——让 τ 输出的一位变化影响尽可能多的输出位。5 路循环移位异或的选择经过精心挑选,使得 L 变换的分支数(Branch Number)达到较优值。
与 AES 线性层的对比
| 属性 | AES MixColumns | SM4 线性变换 L |
|---|---|---|
| 数学基础 | GF(2^8) 矩阵乘法 | 循环移位 + 异或 |
| MDS 性质 | 是(最大距离可分) | 否 |
| 分支数 | 5(理论最优) | 无简单度量 |
| 扩散速度 | 2 轮完全扩散 | 需要更多轮 |
| 实现复杂度 | 需要 GF(2^8) 乘法 | 仅移位和异或 |
SM4 的 L 变换不是 MDS,但通过 32 轮的累积效应,仍然达到了足够的扩散。这是一个以轮数换复杂度的设计取舍。
密钥扩展中的 T' 变换
SM4 的密钥扩展使用了一个类似的变换 T' = L' ◦ τ,其中 τ 使用同一个 S 盒,但线性变换 L' 不同:
L'(B) = B ⊕ ROL(B,13) ⊕ ROL(B,23)注意 L' 使用 13 和 23 的移位(vs 加密用的 2、10、18、24)。这种差异确保了轮密钥与加密轮函数使用不同的线性变换,防止滑动攻击。
密钥扩展算法
SM4 的密钥扩展将 128-bit 主密钥扩展为 32 个 32-bit 轮密钥(共 1024 bit)。
算法步骤
输入: 主密钥 MK = (MK0, MK1, MK2, MK3) // 4 个 32-bit 字
步骤 1: 初始化
(K0, K1, K2, K3) = (MK0 ⊕ FK0, MK1 ⊕ FK1, MK2 ⊕ FK2, MK3 ⊕ FK3)
FK = (0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC) // 系统参数
步骤 2: 迭代生成轮密钥(i = 0, 1, ..., 31)
tmp = K[i+1] ⊕ K[i+2] ⊕ K[i+3] ⊕ CK[i] // CK: 固定常量
tmp = τ(tmp) // S 盒替换
tmp = L'(tmp) // 线性变换
rk[i] = K[i] ⊕ tmp
K[i+4] = rk[i] // 滑动窗口
输出: 轮密钥 rk[0], rk[1], ..., rk[31]固定常量
FK(系统参数)和CK(轮常量)是标准规定的固定值:
FK = (0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC)
CK[i] = (ck_{i,0}, ck_{i,1}, ck_{i,2}, ck_{i,3})
其中 ck_{i,j} = (4i + j) × 7 (mod 256)CK 的生成极其简单——线性公式 (4i+j)×7 mod 256,与 AES 的 Rcon(GF(2^8) 中 2 的幂次)形成鲜明对比。这种简单性在硬件实现中意味着 CK 可以即时计算,不需要存储。
与 AES 密钥扩展的对比
| 属性 | AES-128 密钥扩展 | SM4 密钥扩展 |
|---|---|---|
| 非线性频率 | 每 4 列一次 S 盒 | 每轮一次 S 盒 |
| 常量来源 | Rcon = GF(2^8) 幂次 | CK = 线性公式 |
| 扩展复杂度 | 低(大部分是 XOR 链) | 较高(每轮完整 T' 变换) |
| 相关密钥安全 | AES-256 有已知弱点 | 无已知弱点 |
| 密钥长度灵活性 | 128/192/256 三档 | 仅 128 bit |
安全分析
差分密码分析
差分密码分析是分组密码最强大的已知攻击方法之一。其核心思想是:利用明文对的差分(XOR 差)与密文对的差分之间的统计关系来恢复密钥。
对于 SM4:
- S 盒的差分均匀度为 4:意味着对于任意非零输入差分 Δx,满足 S(x) ⊕ S(x⊕Δx) = Δy 的 x 最多有 4 个
- 最佳差分特征:文献表明,SM4 的 32 轮完整版本的最佳差分特征概率远低于 2^{-128}
- 安全轮数:目前最好的差分攻击覆盖约 22-24 轮,距离完整的 32 轮有充足的安全余量
线性密码分析
线性密码分析利用明文、密文和密钥之间的线性逼近来恢复密钥。
- S 盒的线性逼近度为 16:这是 8-bit S 盒的最优值
- 线性壳(Linear Hull):SM4 的线性分析需要考虑线性壳效应(多条路径的概率叠加)
- 安全余量:目前最好的线性攻击覆盖约 22-24 轮,32 轮完整版本有足够余量
积分攻击(Square 攻击)
积分攻击(也称为 Square 攻击或 Saturation 攻击)对 AES 类 SPN 密码特别有效。
对 SM4 的积分攻击研究表明:
- 由于 SM4 的 Feistel 结构,积分属性的传播比 SPN 更慢
- 目前最好的积分攻击覆盖约 20 轮
- 32 轮完整版本有充足的安全余量
不可能差分攻击
不可能差分攻击通过寻找概率为零的差分路径来排除错误的密钥候选。
- 文献报道了 SM4 的 23 轮不可能差分攻击
- 完整 32 轮的安全余量约为 9 轮
量子计算威胁
Grover 算法对对称密码的影响是将有效安全强度减半:
| 算法 | 经典安全强度 | 量子安全强度(Grover) |
|---|---|---|
| SM4 (128-bit key) | 128 bit | 64 bit |
| AES-128 | 128 bit | 64 bit |
| AES-256 | 256 bit | 128 bit |
目前 SM4 仅有 128-bit 密钥版本,尚无 SM4-256 的标准扩展。
PQC 迁移路径:为应对量子威胁,业界主要采用以下方案增强 SM4 的安全性:
- 混合加密:SM4 + ML-KEM(FIPS 203)混合 KEM,在密钥交换阶段引入 PQC 保护
- 增大密钥长度:使用 SM4-256(若标准化)将量子安全强度恢复到 128 bit
- 多层加密:SM4 外层包裹 AES-256,确保至少有一层在量子场景下安全
- 关注 NIST 和国密标准演进:SM4 的后量子增强方案正在研究中
SM4 vs AES:设计哲学对比
两条路线的取舍
AES 和 SM4 都是优秀的 128-bit 分组密码,但设计哲学截然不同:
AES 的设计哲学 SM4 的设计哲学
────────────── ──────────────
"用最少的轮数达到安全" "用最简单的轮函数 + 更多轮数达到安全"
┌─────────────────┐ ┌─────────────────┐
│ 复杂轮函数 │ │ 简单轮函数 │
│ (4 步 SPN) │ │ (异或+查表+移位) │
│ 10 轮 │ │ 32 轮 │
│ 快速扩散 │ │ 慢速扩散 │
│ 解密需要逆电路 │ │ 加解密几乎相同 │
└─────────────────┘ └─────────────────┘硬件加速生态
这是 AES 目前最大的优势:
| 平台 | AES 加速 | SM4 加速 | 差距 |
|---|---|---|---|
| x86 (Intel/AMD) | AES-NI(2010+) | 无原生指令 | ~19×(量级估算,取决于工作负载) |
| ARM (鲲鹏/飞腾) | Crypto Extension | Crypto Extension | ~1.7×(量级估算) |
| Apple Silicon | Crypto Engine | 无原生指令 | ~21×(量级估算) |
| FPGA/ASIC | 专用电路 | 专用电路 | 持平 |
AESENC 指令一条就能完成一整轮 AES 加密(SubBytes + ShiftRows + MixColumns + AddRoundKey),延迟约 4 个时钟周期。SM4 没有原生指令,需要用多条通用指令模拟。SM4 在 x86 上的加速思路:
- AES-NI 模拟:利用
AESENCLAST指令(只做 SubBytes)来加速 SM4 的 S 盒查找 - GFNI 指令集:Intel Ice Lake 引入的 GF(2^8) 仿射变换指令可以加速 SM4 S 盒的仿射层
实现面积(硬件)
在 ASIC/FPGA 实现中,SM4 的面积优势明显:
- SM4 的加密和密钥扩展可以复用同一个 S 盒(加密用 L,扩展用 L')
- AES 需要独立的 S 盒和逆 S 盒(解密时需要 InvSubBytes)
- SM4 的轮函数不需要 GF(2^8) 乘法器,面积更小
标准化与合规
国内标准体系
| 标准编号 | 名称 | 说明 |
|---|---|---|
| GB/T 32907-2016 | 信息安全技术 SM4 分组密码算法 | 算法主体标准 |
| GM/T 0002-2012 | SM4 分组密码算法 | 行业标准(旧版) |
| GB/T 37092-2018 | 信息安全技术 密码模块安全要求 | 涉及 SM4 实现检测 |
国际标准化
- ISO/IEC 18033-3:2010:SM4 已被纳入国际标准(块密码算法集)
- IETF draft-ribose-cfrg-sm4-04:CFRG 发布的 informational draft
- TLS 国密标准:GM/T 0024(国密 SSL)和 RFC 8998(国密 TLS 1.3)中定义了 SM4 在 TLS 中的使用方式
合规要求
在以下场景中,SM4 是强制性或推荐性的加密算法:
- 金融行业(央行要求)
- 关键信息基础设施(等保三级以上)
- 政务系统(电子政务密码应用要求)
- 密评(商用密码应用安全评估)
参考来源
- GB/T 32907-2016, 信息安全技术 SM4 分组密码算法
- draft-ribose-cfrg-sm4-04, The SM4 Blockcipher Algorithm And Its Modes Of Operations, IETF CFRG
- Diffie, W. & Ledin, G., "A Cryptographic Review of SMS4", IACR ePrint 2008/329
- quant67.com - SM4 vs AES:分组密码的两条路线
- Kopaldev - The ShāngMì 4 (SM4) Block Cipher: A Deeper Look
- NIST FIPS 197, Advanced Encryption Standard (AES)
相关实践
- 如需了解 SM4 在 TLS 部署中的完整流程,请参阅《SM2 国密算法实战:从密钥生成到 TLS 完整部署》
- 如需了解 SM4-GCM 模式的工程实现,请参阅《SM4-GCM 模式实战:AEAD 认证加密的实现与陷阱》
- 如需了解国密 HTTPS 部署过程中的常见问题,请参阅《国密 HTTPS 踩坑实录:从开发到上线的 12 个坑》