SM4 加密详解:国密对称加密标准
什么是 SM4?
SM4 是中国国家密码管理局发布的分组对称加密算法,2006 年作为行业标准 GM/T 0002 首次发布,2012 年升格为国家标准 GB/T 32907-2016。它和 AES 在定位上完全对应——都是把数据切成 128 位的块、用同一把密钥加解密,只是 SM4 的密钥长度固定为 128 位。
为什么国内项目经常非用 SM4 不可?因为合规。等保 2.0(网络安全等级保护 2.0)明确要求关键信息基础设施”优先使用商用密码算法”,而”商用密码算法”在国密体系里就是 SM 系列。政务系统、银行核心系统、支付接口(如银联、微信支付的部分通道)在做密码改造时,AES 往往要替换成 SM4。所以哪怕 SM4 在国际上不如 AES 流行,国内开发者也绕不开它。
国密家族里 SM2 是非对称加密、SM3 是哈希、SM4 是对称加密——这套组合基本对标国际上的 ECC + SHA-256 + AES。
SM4 的工作原理
和 AES 一样,SM4 是分组密码:数据按 16 字节切块,每块独立加密。但它和 AES 在内部结构上有个本质区别——
| 对比项 | AES | SM4 |
|---|---|---|
| 分组长度 | 128 位 | 128 位 |
| 密钥长度 | 128/192/256 位 | 固定 128 位 |
| 轮数 | 10/12/14 轮 | 固定 32 轮 |
| 结构 | 标准 Feistel 变体(SPN) | Feistel 变体(非平衡) |
| 轮函数 | SubBytes/ShiftRows/MixColumns/AddRoundKey | 合成 T 函数 + 轮密钥加 |
SM4 走的是 Feistel 网络的变体:每一轮把 128 位状态分成 4 个 32 位字 (X0, X1, X2, X3),输出下一组状态时,新字由前三轮的字加上一个非线性变换后的第四个字异或得到。32 轮跑完再做一次反序变换输出密文。
核心部件:S 盒与合成变换 T
SM4 的非线性来源是一个 8 进 8 出的 S 盒(和 AES 的 S 盒不同,是国密自己设计的置换表)。轮函数里的合成变换 T 由两部分组成:
- τ(并行 S 盒替换):把 32 位输入拆成 4 个字节,每个字节过一次 S 盒
- L(线性扩散):对替换后的 32 位做循环移位和异或——
B ⊕ (B<<<2) ⊕ (B<<<10) ⊕ (B<<<18) ⊕ (B<<<24)
τ 负责”混淆”(让输入输出关系复杂),L 负责”扩散”(让 1 位的变化影响整个字)。混淆和扩散合起来就是 Shannon 提出的密码设计两大原则,SM4 和 AES 在这点上思路一致,只是实现方式不同。
密钥扩展
SM4 用一个和加密轮函数结构类似的算法(只是把线性变换 L 换成更简单的 L’),从 128 位主密钥 + 系统参数 FK 生成 32 个轮密钥。密钥扩展里用到的 CK 是固定参数常数表,保证每轮密钥都不一样且不可逆推。
SM4 vs AES:该用哪个?
技术层面两者都是安全的分组密码,没有”谁更强”的定论。选择主要是场景驱动:
- 国内合规场景(政务、金融、等保 2.0、密码改造):必须 SM4,没得选
- 国际通用 / 性能优先:AES 更成熟,硬件加速(AES-NI 指令集)普及,速度快
- 跨境系统:常见做法是双算法支持,国内流量走 SM4,国际流量走 AES
性能上,因为 AES 有 CPU 原生指令加速,纯软件实现的 SM4 通常比 AES 慢一些;但现代服务器上 SM4 的性能也完全够用,加密几 MB 数据是毫秒级的事。
分组模式
SM4 本身只加密一个 16 字节块,处理长数据要靠分组模式——这一点和 AES 完全一样,常见模式:
- ECB:每块独立加密。简单但相同明文块产生相同密文块,会暴露数据模式,不建议用
- CBC:每块先和前一块密文异或再加密,需要 IV(初始化向量)。最常用
- CTR:把密钥和计数器加密生成密钥流,再和明文异或。可并行,速度快
- GCM:CTR + 认证标签,既加密又防篡改。现代首选
实际项目里 SM4-CBC 和 SM4-GCM 用得最多。用 CBC 时 IV 必须随机且每次不同(可以公开),否则同样的明文+密钥会得到同样密文。
常见坑
- IV 不能复用:CBC 模式下 IV 重复会泄露明文是否相同。正确做法是每次加密用随机 IV,把 IV 拼在密文前面一起传输
- 密钥要安全存储:SM4 密钥本身就是 16 字节随机串,别硬编码在代码里,应该走 KMS(密钥管理服务)或环境变量
- 加密 ≠ 认证:光用 CBC 加密,攻击者可以篡改密文而不被发觉。要防篡改得加 MAC(如 HMAC-SM3)或直接用 GCM 模式
- 填充:CBC 需要明文是 16 字节整数倍,不够要补齐(PKCS#7 填充最常见)。解密时记得去掉填充
小结
SM4 是国密体系里的对称加密担当,技术上是一个设计扎实、轮数充足(32 轮)的 Feistel 变体分组密码。对国内开发者来说,理解它的意义更多在于合规——当项目要求过等保、对接政务金融系统时,SM4 是绕不开的必选项。原理上和 AES 是同路人,掌握了 AES 的分组模式、填充、IV 这些概念,迁移到 SM4 几乎零成本。
想对比国密全家桶,可以看看非对称的 [[sm2]] 和哈希算法 [[sm3]]。