SM4 算法的前世今生
1.1 从国密标准到商用密码
说起 SM4,我得先聊聊它的“身份证”。2006 年,国家密码管理局发布了一套分组密码算法,当时还叫 SMS4。说白了,就是要搞一套中国人自己的对称加密标准。2012 年它正式成为国标 GB/T 32907-2016,2016 年又成为国际 ISO/IEC 标准的一部分。
我最早接触 SM4 是在 2015 年做一个政务系统。客户要求必须用国密算法,我当时还嘀咕:“跟 AES 能差多少?”结果一上手发现,密钥长度一样是 128 位,但轮数多了 32 轮,S 盒是自定义的——这套设计其实很有讲究。
关键时间节点:
- 2006 年:国家密码管理局发布 SMS4 标准
- 2012 年:上升为国家标准 GB/T 32907
- 2016 年:成为 ISO/IEC 18033-3 国际标准
- 2021 年:进入商用密码产品认证目录
1.2 算法家族定位
国密体系里有 SM2、SM3、SM4、SM9,相信很多同学都听过。它们各自扮演什么角色?我列个表,这样更清楚。
| 算法 | 类别 | 主要用途 | 密钥长度 |
|---|---|---|---|
| SM2 | 非对称加密 | 密钥交换、数字签名 | 256 位 |
| SM3 | 哈希算法 | 消息摘要、完整性校验 | 256 位摘要 |
| SM4 | 对称加密 | 数据加密保护 | 128 位 |
| SM9 | 基于身份的密码 | 无证书密钥管理 | 256 位 |
你看,SM4 是唯一一个对称加密算法,专管大批量数据的加解密。我在项目中做过一次选型对比:国密要求必须用 SM4,但系统要兼容国际标准。最后采用了 SM4 加 AES 双模式,根据不同安全等级切换——嗯,这个后面会讲到具体实现。
1.3 SM4 的核心技术特性
SM4 是一个分组密码算法,分组长度 128 位,密钥长度也是 128 位。你想想看,128 位的密钥空间是 2128,现阶段的算力基本上不可能暴力破解。
它的核心结构是 32 轮迭代的 Feistel 网络。每轮有一个轮函数 F,包含非线性变换和线性变换。我简单拆解一下:
- 分组: 128 位输入,分成 4 个 32 位字
- 密钥扩展: 128 位初始密钥生成 32 个 32 位轮密钥
- 轮函数 F: 包含 S 盒替换(非线性)、L 变换(线性移位异或)
- 轮数: 32 轮,最后对输出进行反序变换
- 解密: 与加密结构相同,仅轮密钥使用顺序相反
有一个小细节让我印象深刻:SM4 的 S 盒只有 8×8 比特,也就是 256 字节。相比 AES 的 16×16 S 盒,它更紧凑,在嵌入式设备上实现效率很高。我曾经在一个 ARM Cortex-M3 上跑 SM4 软件实现,加密速度大概在 5MB/s,完全满足物联网场景需求。
工程师经验: 如果你需要自己实现 SM4,最容易被坑的是密钥扩展中 CK 常量的取值。手册里那个 32 位常量数组,很多人直接复制粘贴少了 0x 前缀。我建议直接从官方标准文档里拷,或者用成熟的库(如 gmssl、pysmx)。
1.4 我为什么选择 SM4
2017 年我负责一个金融数据交换平台,甲方要求端到端加密。当时有两个选项:AES-128 或 SM4。AES 性能更好,生态更成熟;但政策要求金融核心系统使用国密。怎么办?
我带队做了一个白盒测试:在相同硬件(Intel Xeon E5)上,OpenSSL 的 AES-128-CBC 速度约为 280MB/s,而 GmSSL 的 SM4-CBC 约为 190MB/s。差距是有的,但没到不可接受的程度。最终我们选择了 SM4,并在中间件层做了缓存和批量加密优化,实际体验几乎感觉不到差异。
从那之后我就养成了习惯:只要涉及国密合规,优先用 SM4;如果只是内部实验或海外项目,才考虑 AES。你想想看,密码算法就跟选工具一样——合规性有时候比性能更重要。
注意事项: 不要在同一个系统里同时使用 SM4 和 AES 的硬编码密钥。我曾经见过有人把 SM4 密钥硬编码在配置文件里,结果被扫描工具发现了。一定要使用密钥管理服务或硬件安全模块来存储主密钥。
1.5 SM4 知识体系全景图
这一章内容不多,但为了让你对整个学习路径有个直观印象,我画了一张图。它涵盖了从基础理论到落地实现的全部要点。后面的章节会逐一展开。
1.6 本章小结
这一章我们快速过了 SM4 的来历、技术特点、在国密家族中的位置。你记住三个关键词就行:128 位分组、32 轮迭代、Feistel 网络。后面的章节我会带你亲手实现密钥扩展、轮函数,并且写 Python 代码对接 SM4 接口。
对了,下次你看到“国密SM4”这几个字,脑子里浮现的应该不只是“一个加密算法”,而是一整套从标准到工程化的体系——这也是我这么多年摸爬滚打之后最深的体会。