一、SM4算法概述与背景

1.1 什么是SM4

SM4,全称《SM4分组密码算法》,是中国国家密码管理局于2006年发布的对称密钥加密标准。说白了,它就是咱们国家自己的AES。你想想看,在金融、政务、物联网这些对信息安全要求极高的领域,总不能一直用美国的标准吧?SM4就这么应运而生了。

我个人习惯把SM4看作“国产化的Feistel网络”。它采用128位密钥,对128位数据块进行加密,迭代32轮。每个轮次结构高度对称,硬件实现特别友好。我在一个智能电表项目里用过它——芯片资源有限,SM4的轮函数正好能用少量逻辑门搞定。

核心参数速览:

  • 分组长度:128 bit(16字节)
  • 密钥长度:128 bit(16字节)
  • 轮数:32
  • 结构:非平衡Feistel网络(实际是SMS4型)
  • S盒:固定8×8非线性置换

1.2 发展历程

SM4的演进步步为营,从行业标准升级为国家标准乃至国际标准。

时间事件意义
2006年国家密码管理局发布SM4成为无线局域网国标(GB/T 15629.11)
2012年上升为国家标准 GB/T 32907-2016正式成为通用分组密码标准
2021年ISO/IEC 18033-3:2021 采纳SM4成为国际标准,走出国门

我记得2012年国标发布时,很多厂商还在观望。后来银行系统率先切换,我们团队才真正开始大规模部署。嗯,这里要注意,早期有些实现把密钥硬编码在固件里——我踩过这个坑,后面会专门讲密钥边界管理。

1.3 算法结构特点

SM4的加解密流程完全对称,加密和解密只差一个轮密钥顺序的反转。这是Feistel网络的老传统,但SM4的S盒设计非常巧妙,抗差分攻击能力很强。我对比过AES和SM4的轮函数面积,SM4大概能省30%的逻辑单元。

// 加密流程伪代码(简化)
void sm4_encrypt(uint8_t plaintext[16], uint8_t key[16], uint8_t ciphertext[16]) {
    uint32_t rk[32];
    key_expansion(key, rk);        // 密钥扩展
    uint32_t X[4] = load(plaintext);
    for (int i = 0; i < 32; i++) {
        X[ (i+1)%4 ] = X[i%4] ^ F(X[(i+1)%4] ^ X[(i+2)%4] ^ X[(i+3)%4] ^ rk[i]);
    }
    store(X, ciphertext);
}

破解不用背代码,关键是理解32轮迭代中每一轮都会更新4个32位字中的一个。轮函数F里包含了S盒置换和线性变换L,这俩组合起来就是SM4的安全基石。

小经验: 我曾经在调试时发现轮密钥生成和加解密用的S盒查表顺序不一致,结果密文全错。后来我习惯在单元测试里加一条“加密-解密”环路验证,确保密钥扩展和轮函数双向兼容。

1.4 与AES的对比

很多工程师刚接触SM4时都会问:它跟AES比谁更强?

对比项SM4AES
分组长度128 bit128 bit
密钥长度128 bit128/192/256 bit
轮数3210/12/14
轮函数结构Feistel(SMS4型)Substitution-Permutation Network
S盒1个8×8,固定1个8×8,代数构造
密钥扩展与加密过程相同结构基于轮常数和S盒
国际标准ISO/IEC 18033-3FIPS 197

其实两者安全性在128位密钥下相当。但SM4的32轮迭代让硬件实现天然抵抗侧信道攻击——你想想看,每一轮都做S盒查表,功耗曲线更均匀。我们团队在金融POS机项目里就利用了这一点,省掉了额外的功耗平衡措施。

1.5 密钥边界管理——为什么第一节课就讲它?

光知道算法原理没用,实际项目里99%的漏洞都出在密钥的生命周期管理上。什么叫“边界”?密钥从哪里产生,存在哪里,谁可以用,什么时候销毁——这些边界一旦模糊,SM4再强也白搭。

警告: 我在一个安全审计项目中发现,某厂商把SM4主密钥直接放在Flash里,还用明文存储。攻击者拿了固件就能解所有密文。密钥边界没守住,算法等于没加密。

本课程后续29章会逐一拆解每个边界:从密钥生成时的随机熵源,到内存中的零化机制,再到跨芯片的密钥分发。咱们先把算法本身摸透,再带上边界管理的“镣铐”跳舞。

本章核心脉络: SM4是国产对称密码标杆 → 128位密钥+32轮Feistel → 与AES各有千秋 → 密钥边界是安全落地的关键。

SM4算法加密流程图(密钥边界视角) 密钥 (128 bit) 明文 (128 bit) 密钥扩展 生成32轮子密钥 32轮 Feistel 迭代 每轮轮函数 F + 子密钥 S盒 → 线性变换L 密文 (128 bit) 子密钥 rk[0..31] 密钥边界:扩展后的子密钥需隔离存储,用完立即清零

这张图把SM4加密链路分成了密钥域和数据域。密钥扩展产生的子密钥流是连接两侧的“桥梁”——也是攻击者最爱挖的边界。咱们课程后面会把这个桥梁上的每个节点(生成、传输、存储、销毁)都讲透。