SM4算法概述:国密标准、算法特点与安全强度
这部分内容我打算先聊聊 SM4 到底是个啥。说实话,很多刚接触国密的同学总觉得 SM4 就是 AES 的仿制品 —— 其实差别还挺大。我在接手第一个国密项目时,就踩过这个认知坑:以为能用 AES 的代码简单改改就能跑通 SM4,结果轮函数结构完全不同,调试了一整天。嗯,从那以后我学会了:先读标准,再动手。
国密标准里的 SM4
SM4 是国家密码管理局发布的对称分组密码算法,2012 年成为国标 GB/T 32907-2016。2021 年它正式进入国际标准 ISO/IEC 18033-3 的修订版,这意味着 SM4 已经不只是国内用了,海外厂商也开始集成。我记得 2022 年有个海外客户要求我们的产品必须支持 SM4,我当时还专门确认过他们是否了解这个算法的来源 —— 结果人家拿出了 ISO 标准号,反过来给我上了一课。
SM4 与 SM2、SM3 并称国密“三件套”,实际业务中经常组合出现:SM2 做密钥协商,SM3 做哈希认证,SM4 做批量数据加密。你想想看,一个完整的国密通信方案,缺了 SM4 还真跑不起来。
算法特点:跟 AES 到底有啥不同?
先上一张对比表,你一看就明白。
| 对比项 | SM4 | AES-128 |
|---|---|---|
| 分组长度 | 128 bit | 128 bit |
| 密钥长度 | 128 bit | 128 bit |
| 轮数 | 32 轮 | 10 轮 |
| 结构类型 | Feistel 网络(非标准) | SPN 结构 |
| S 盒规模 | 8×8 位,256 字节 | 8×8 位,256 字节 |
| 密钥扩展 | 32 轮密钥,线性反馈移位 | 10 轮密钥,轮常量加 |
SM4 的 Feistel 结构跟经典 DES 不太一样。经典 Feistel 每轮只变换一半数据,而 SM4 每轮变换整个 128 位的四分之一(32 位),然后通过异或和移位打散。说白了,它是个 非平衡 Feistel 网络。我刚开始看标准文档时,被图中弯弯曲曲的连线绕晕了,后来自己画了一次数据流才彻底搞懂。
密钥扩展也很有特色。SM4 用 128 位主密钥生成 32 个 32 位轮密钥,过程中使用了与加密相同的 S 盒和线性变换。这种“复用”设计的好处是硬件实现可以共用 S 盒资源。我记得有个嵌入式项目,Flash 只有 64KB,S 盒重复利用正好省了空间。
安全强度:够用,但要小心用
- 抗差分&线性分析: SM4 的差分均匀性和线性逼近优势都经过了严密测试,32 轮安全冗余充足。目前公开中最优的攻击只到 28 轮,离 32 轮还差得远。
- 抗穷举攻击: 128 位密钥空间,暴力破解不现实。这个强度跟 AES-128 在同一量级。
- 侧信道防护: 这是我自己最关心的地方。SM4 标准没有规定实现时的防护措施,但实际场景中 必须 加掩码或隐藏。我之前做过一个安全模块,初始版本没加掩码,示波器上一眼就能看出密钥相关的功耗差异。后来补了随机掩码,才好很多。
SM4 在国密体系中的位置
为了让全局关系更清晰,我画了下面这张图。你可以看到 SM4 是底层对称加密核心,上面支撑着各种应用协议。
图里蓝色分组是算法顶层,绿色/橙色/红色/紫色分别代表不同密码原语。SM4 节点下延伸出四个核心模块:32 轮迭代、S 盒、线性变换和密钥扩展。你看到最下面的黄色提醒框了吗?那就是我刚刚说的 —— 抗侧信道要靠实现层来补,算法标准本身不背这个锅。
一个真实的小教训
我个人习惯在项目启动阶段就用标准测试向量验证加密结果。SM4 的官方测试向量在 GB/T 32907 附录里有,拿它跟 OpenSSL 或 GmSSL 的输出对一遍,基本能发现大部分实现 bug。我曾经以为公司自研的加密库没问题,结果用测试向量一跑,第 18 轮之后的密文就开始偏移了 —— 原因是轮密钥生成时有个循环移位方向写反了。幸亏发现得早,没进入生产环境。
密钥:0123456789abcdeffedcba9876543210
明文:0123456789abcdeffedcba9876543210
对应密文(前四轮可逐轮对比标准文档)。