第2章 对称加密算法SM4:从原理到实战
聊完分层架构的整体思路,咱们得先吃透最核心的加密算法。你在项目中用SM4,不能只会调个API——得知道它肚子里装的是什么。我个人习惯,讲算法一定从“它解决了什么问题”开始。
SM4,说白了就是国标里定义的对称分组密码算法。块大小128位,密钥长度128位,轮数32轮。你想想看,和AES-128相比,块和密钥尺寸一样,但轮数更多(AES只有10/12/14轮)。为什么?因为SM4的轮函数结构更轻量,靠轮数堆安全强度。
算法核心结构
SM4是Feistel网络结构,和一个叫“非平衡Feistel”的说法有关。不过别被名字吓到,它的加解密流程一模一样——只是轮密钥使用顺序相反。这在硬件实现里是个大优势,我当年做FPGA加速时就因为这特性省了不少逻辑门。
整个流程分为三个部分:
- 密钥扩展:从128位主密钥生成32个32位轮密钥
- 32轮迭代:每轮用一个轮密钥,做非线性变换和线性变换
- 反向变换:最后把输出再做个简单重组得到密文
嗯,这里要注意:SM4的加解密只有轮密钥顺序不同,其他完全对称。解密时把轮密钥数组倒序使用就行。
轮函数拆解
每轮变换的核心叫F函数,输入四个字节X0~X3和一个轮密钥rk,输出一个字节。公式如下:
F(X0, X1, X2, X3, rk) = X0 ⊕ T(X1 ⊕ X2 ⊕ X3 ⊕ rk)
这里的T变换分成两步:非线性替换(S盒)和线性变换(L)。
S盒:查表就好
SM4的S盒和AES一样是8×8的,但值完全不同。254个元素,固定查表。不要自己去算,直接拿标准里的256字节数组。我见过有人试图用数学公式推导S盒,结果算错了一个字节,整个算法全废。别折腾,用现成的。
线性变换L
L是一个32位的循环移位+异或操作:
输出的32位B,经过L变换:
L(B) = B ⊕ (B <<< 2) ⊕ (B <<< 10) ⊕ (B <<< 18) ⊕ (B <<< 24)
这个设计让扩散性非常快。我记得做安全分析时,两轮之后每个输出位就与所有输入位相关了。
密钥扩展算法
主密钥MK分成MK0~MK3四个32位字。先和固定参数FK做异或:
K0 = MK0 ⊕ FK0
K1 = MK1 ⊕ FK1
K2 = MK2 ⊕ FK2
K3 = MK3 ⊕ FK3
然后循环生成32个轮密钥:
rki = Ki+4 = Ki ⊕ T'(Ki+1 ⊕ Ki+2 ⊕ Ki+3 ⊕ CKi)
这里的T'和加密的T结构一样,但线性部分换成了简单的移位:
T'(B) = B ⊕ (B <<< 13) ⊕ (B <<< 23)
CK是固定常数,每个轮次不同。我给你个快速检查方法:算出第一个轮密钥,如果和标准测试向量对不上,八成是CK顺序搞错了。
加解密流程对比
| 步骤 | 加密 | 解密 |
|---|---|---|
| 输入 | 128位明文 | 128位密文 |
| 密钥扩展 | rk0~rk31(顺序) | rk31~rk0(反序) |
| 轮操作 | 32轮F函数 | 32轮F函数 |
| 最后变换 | 将(X1,X2,X3,X0)重组为密文 | 将(X1,X2,X3,X0)重组为明文 |
你没看错,最后变换只是简单的字节重排。这个设计让硬件实现省了不少逻辑。
SM4相比AES的优劣势
- 优势:加解密共用电路,节省面积;轮函数简单,适合低成本芯片;国密标准,国内合规必须用。
- 劣势:软件实现速度通常比AES慢(因为32轮);国际认可度不如AES;S盒设计缺乏公开密码分析(虽然目前没发现漏洞)。
- 我个人建议:如果只是国内合规项目,优先用SM4;如果涉及国际互通,用AES或者SM2+SM3做密钥协商后选AES。
一个实际案例:我在做物联网终端时,设备主控是ARM Cortex-M0,内存只有8KB。用SM4的ECB模式,密钥扩展预计算存入Flash,运行时只查表和移位,每一轮大概300个时钟周期,32轮总共不到1万周期,完全够用。比用AES的查表实现还快一点——因为SM4的S盒只有256字节,比AES的T表(4KB)省缓存。
SM4算法结构图
下面这张图把SM4的核心数据流画出来了。你看懂了它,就懂了SM4整个框架。
从图里能清楚看到:主密钥走密钥扩展,生成32个轮密钥;明文进入32轮迭代,每轮用F函数做S盒和L变换;最后一轮做完再做个反序重组,就得到密文了。
实战中你需要注意的
- 模式选择:SM4支持ECB、CBC、CTR、OFB、CFB等模式。我建议只要没兼容性限制,优先用CTR或CBC+随机IV。ECB有模式缺陷,别用了。
- 填充方式:分组密码需要填充。PKCS7最常用。SM4标准里也推荐PKCS7。
- 性能调优:如果软件实现,可以用预计算轮密钥查找表(类似AES的T表),把S盒和L变换合并成4个32位表,每轮从4次查表变成1次,速度能提升3~4倍。我有个项目靠这个将SM4吞吐从200Mbps提到800Mbps。
- 安全考虑:SM4没有已知的旁路攻击漏洞?不,任何对称算法都要防侧信道。如果你的设备暴露在物理环境下,建议加掩码或者使用固定的延迟操作。我曾经审计过一个POS机固件,SM4时间常数变了,攻击者通过电磁分析恢复了部分轮密钥。
一句话总结:SM4就是一个128位Feistel网络,32轮,S盒+循环移位。记住密钥扩展用FK/CK,加解密只有密钥顺序不同。练习时拿官方测试向量(GB/T 32907附录A)调试,一次过就算真懂了。