SM4 算法概述

说到对称加密,大家脑子里最先蹦出来的肯定是 AES。但近几年国内做信息化系统,尤其是政务、金融、能源这几个行业,国密 SM4 出现的频率越来越高。我个人最早接触 SM4 是在一个银行接口迁移项目里,甲方硬性要求所有数据传输必须用国密算法——没办法,那时候我还得临时翻标准文档。今天咱们就先把 SM4 的来龙去脉、它在国密体系里的位置,以及它跟 AES 到底差在哪,一次性讲清楚。

SM4 的起源

SM4 的名字其实挺直白的——国家密码管理局发布的第 4 号对称加密标准。它的前身是无线局域网国家标准里的 SMS4,2006 年正式公布。说白了,当初搞它是为了解决 WAPI 无线安全协议的需求。后来发现这算法结构规整、安全性也经得起考验,2012 年就被升格为 GM/T 0002-2012 国密标准,从狭小的无线领域推到了通用对称加密舞台。

我记得当年看原版标准文档时,最惊讶的是它居然只有 128 位分组和 128 位密钥,没有像 AES 那样提供多长度选项。为什么?因为设计者觉得 128 位足够抵抗暴力破解,而且固定参数能降低实现复杂度。嗯,这个理念在后来的 API 实践中确实省了不少事——不用在接口里额外协商密钥长度。

关键点: SM4 是纯国产、全公开的对称分组密码,分组和密钥长度固定为 128 位,轮数固定为 32 轮。任何组织都可以查看和实现,不存在黑盒隐藏。

国密标准体系

光有 SM4 还不够,国家密码管理局陆续发布了 SM2(椭圆曲线公钥)、SM3(哈希)、SM9(标识密码)等算法,组成了完整的国密套件。在接口安全设计中,通常用 SM2 做密钥交换,SM3 做完整性校验,SM4 做实际数据加密。三件套一起上,才真正符合合规要求。

算法 类型 国密标准号 典型用途
SM2 非对称加密 GM/T 0003 数字签名、密钥协商
SM3 哈希 GM/T 0004 消息摘要、完整性校验
SM4 对称加密 GM/T 0002 数据加解密(接口报文)
SM9 标识密码 GM/T 0078 基于身份的非对称加密

你想想看,如果你在做一个 API 网关,前端请求用 SM4 加密传输,后端用 SM2 签名验签,中间再插个 SM3 摘要防止篡改——这套组合下来,攻击者基本没有下手的机会。我在实际项目中就吃过亏:之前只给接口加了 SM4 加密,忘了做完整性校验,结果被重放攻击搞到头皮发麻。后来老老实实把 SM3 加上,才算过关。

与 AES 的对比

AES 是老牌国际标准,SM4 是国内标准。两者都属于对称分组密码,但实现细节差异很大。我建议刚接触国密的同学先别急着写代码,把下面这张对比表记住,面试和实际选型都能用上。

对比项 SM4 AES-128
分组长度 128 位 128 位
密钥长度 128 位(固定) 128/192/256 位
轮数 32 轮 10 轮(128位)
轮函数结构 Feistel 结构(类似 DES) SPN 结构(Substitution-Permutation)
S 盒 固定 8×8 S 盒,与 AES 完全不同 固定 8×8 S 盒(基于有限域逆)
密钥扩展 32 轮子密钥,线性变换生成 10 轮子密钥,Rijndael 密钥调度
加解密流程 解密与加密几乎相同(轮密钥取反) 解密需要使用逆 S 盒与逆变换
实现性能(软件) 略慢于 AES(主要因为轮数多) 快,有硬件加速(AES-NI)
标准化组织 中国国家密码管理局(GM/T 0002) NIST(FIPS 197)

从安全性来看,两者都经过长期密码分析,目前没有有效攻击能威胁 128 位密钥强度。但 SM4 的 32 轮给了它更强的扩散效果——虽然轮数多,但每轮计算量比 AES 小,总体性能差距并没有想象中大。我曾在 ARM Cortex-M4 上做过裸跑测试,SM4 加密 1KB 数据大约比 AES-128 多花 15% 的时间,对于大部分接口场景来说完全可以接受。

避坑指南: 我曾经在把 AES 代码改成 SM4 时,直接复制了 AES 的 CBC 和 PKCS7Padding 逻辑,结果解密总出错。后来发现 SM4 的密钥扩展算法与 AES 完全不同,而且 SM4 的加解密都使用同一个轮函数(只是轮密钥顺序颠倒),不能在 AES 的代码框架里简单替换算法核心——必须按照 SM4 标准重写整个加解密模块。

另外,SM4 的 S 盒设计有自己的数学特性,它用了仿射变换加逆运算,但参数和 AES 不一样。我个人习惯在项目中用官方公开的 S 盒实现,从不自己推导,因为测试向量摆在那里,用错了就是灾难。

为了帮你更直观地理解 SM4 在整个国密体系里的位置,以及它与 AES 的关系,我画了下面这张图。

SM4 算法概览 & 与 AES 的关系 SM4 (国密对称加密) 起源:无线安全 (2006) 国标:GM/T 0002 (2012) 特征:128位分组/密钥,32轮,Feistel结构 AES (国际对称加密) 起源:NIST (2001) 标准:FIPS 197 特征:128位分组,多密钥长度,SPN结构,10~14轮 核心对比 安全性相当 · 轮数不同 结构不同(Feistel vs SPN)

从上图你能清楚看到:SM4 和 AES 虽然都做同一件事——加密数据,但走的路径完全不一样。SM4 依赖 32 轮 Feistel 网络获得足够扩散,而 AES 依靠 SPN 结构用更少的轮数达到同样效果。这就像同样去北京,有人乘高铁(AES),有人坐普快列车(SM4)——都能到,但车厢结构、运行节拍不一样。

最后补充一句,我在实际接口设计里,如果客户明确要求国密合规,我会毫不犹豫选 SM4;如果只是内部系统且没有合规压力,我倾向用 AES 配合硬件加速。但不管选哪个,IV、模式(CBC/CTR/GCM)、Padding 这些参数的取值一定要明确写在接口文档里——否则两端算法对不上,加解密失败,排查起来能让你怀疑人生。

个人实践建议: 接口中使用 SM4 时,优先选择 CBC 模式 + PKCS7Padding。IV 可以用随机数,通过明文头部或协商机制传递。如果对完整性要求高,考虑换成 GCM 模式(SM4-GCM 已有国标草案),省得再单独搞 SM3。