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 依赖 32 轮 Feistel 网络获得足够扩散,而 AES 依靠 SPN 结构用更少的轮数达到同样效果。这就像同样去北京,有人乘高铁(AES),有人坐普快列车(SM4)——都能到,但车厢结构、运行节拍不一样。
最后补充一句,我在实际接口设计里,如果客户明确要求国密合规,我会毫不犹豫选 SM4;如果只是内部系统且没有合规压力,我倾向用 AES 配合硬件加速。但不管选哪个,IV、模式(CBC/CTR/GCM)、Padding 这些参数的取值一定要明确写在接口文档里——否则两端算法对不上,加解密失败,排查起来能让你怀疑人生。
个人实践建议: 接口中使用 SM4 时,优先选择 CBC 模式 + PKCS7Padding。IV 可以用随机数,通过明文头部或协商机制传递。如果对完整性要求高,考虑换成 GCM 模式(SM4-GCM 已有国标草案),省得再单独搞 SM3。