国密算法基础:SM2、SM3、SM4 算法原理归纳总结
做政务国密改造,绕不开三个核心算法:SM2、SM3、SM4。说白了,它们就是中国版的 RSA、SHA-256 和 AES。我一开始接触的时候也懵,后来在某个省级政务平台迁移项目里硬啃了一个月,才算真正搞明白它们之间的关系。今天就跟你聊聊这三兄弟的底牌,顺便把我踩过的坑也抖出来。
1. SM4:对称加密,又快又稳
SM4 是对称分组密码算法,密钥长度 128 位,分组长度也是 128 位。嗯,跟 AES-128 对位竞争。它用的是 32 轮非平衡 Feistel 结构,加密和解密过程完全一样,只是轮密钥使用顺序相反。
我的习惯:每次在项目里验证 SM4 加解密结果,我都用标准测试向量先跑一遍。说白了,就是拿官方给的明文和密钥,算出来的密文必须跟官方一毛一样。这一步千万别跳过,我在某次集成就因为字节序没对齐,调了大半天。
SM4 密钥扩展与轮函数
它把 128 位密钥先拆成 4 个 32 位字,经过 32 轮迭代生成 32 个轮密钥。轮函数里最核心的操作是 S 盒替换 + 线性变换 L。L 变换其实就是 32 位字上的循环移位和异或。
// 伪代码示意 — SM4 一轮加密
// X0, X1, X2, X3 为一组 128 位输入
// rk 为当前轮密钥
temp = X1 ^ X2 ^ X3 ^ rk;
temp = S_box_substitution(temp); // 非线性替换
temp = L_transform(temp); // 线性变换
X0_new = X0 ^ temp;
特点总结:SM4 在软件实现上比 SM2 快得多,适合大批量数据加密。但注意,它不提供公钥体系,需要先通过 SM2 等方式协商密钥。
2. SM3:密码杂凑,摘要保真
SM3 生成 256 位杂凑值,也就是 32 字节摘要。它的结构基于 Merkle–Damgård,消息分组 512 位,最后填充。我特别喜欢它的一点:它的压缩函数设计得很紧凑,而且有 64 轮迭代,安全性上对标 SHA-256 甚至略强。
SM3 压缩流程
- 消息填充:先补 1 个 '1',再补 0,直到长度 mod 512 = 448,最后加 64 位长度。
- 初始化 8 个 32 位状态字 V0 ~ V7(有固定初值)。
- 每个 512 位分组经过 64 轮迭代,更新状态字。
- 最终 8 个状态字拼接成 256 位摘要。
我曾经遇到一个坑:SM3 的填充分组长度与 SM2 签名时的消息预处理不一样。SM3 自己内部填充是固定的,但 SM2 签名前会用 SM3 对消息 ZA || M 做杂凑,这个 ZA 包含用户身份和公钥信息。千万别把 SM3 的普通摘要直接丢给 SM2 签名,否则验签会失败。
3. SM2:非对称加密与数字签名
SM2 是基于椭圆曲线的公钥密码体制(国标 GB/T 32918)。它支持加密、数字签名、密钥交换。曲线参数是固定的 256 位素域曲线,私钥是随机整数,公钥是曲线上一个点。
我最初被 SM2 的加密长度吓到:密文比明文长很多,因为它要附带椭圆曲线上的点坐标。但在政务场景下,这反而是优势,因为一次加密一个对称密钥正好够用。
SM2 签名与验签流程
- 签名方:计算
e = SM3(ZA || M);生成随机数 k;计算椭圆曲线点 (x1, y1) = k*G;计算 r = (e + x1) mod n;计算 s = ((1+dA)^-1 * (k - r*dA)) mod n;输出签名 (r, s)。 - 验签方:同样计算 e;计算 t = (r + s) mod n;计算椭圆曲线点 (x1', y1') = s*G + t*PA;检查 r 是否等于 (e + x1') mod n。
关键点:SM2 签名中的随机数 k 必须每次独一无二。我在一个老旧项目里发现有人把 k 写死在代码里,结果签名被重放攻击。这算是政务系统里比较低级但致命的漏洞。
4. 三兄弟的协作关系(SVG 图)
在真实政务改造中,SM2、SM3、SM4 并非各自为战,而是形成一套组合拳。下面这张图展示了典型混合加密流程:
5. 三种算法对比一览
做项目选型的时候,我习惯列一个表格贴在墙上。这里我也给你整理了一份:
| 特性 | SM2 | SM3 | SM4 |
|---|---|---|---|
| 算法类型 | 非对称(椭圆曲线) | 杂凑(Hash) | 对称(分组密码) |
| 密钥/输出长度 | 私钥 256 bit,公钥 512 bit | 摘要 256 bit | 密钥 128 bit |
| 主要用途 | 加密、签名、密钥交换 | 完整性校验、数字摘要 | 数据加密 |
| 性能比较 | 较慢(适合小数据) | 中等 | 快(适合大数据) |
| 安全性等级 | 等效 RSA-3072 | 等效 SHA-256 | 等效 AES-128 |
| 国标编号 | GB/T 32918 | GB/T 32905 | GB/T 32907 |
6. 实际改造中的避坑指南
- 字节序:SM2 和 SM4 的接口通常要求大端序,但有些硬件加密卡是小端。我曾在一次跟密码机对接时,因为字节序反了,加密解密对了,签名验签却一直失败,心里那个憋屈……后来用
memcpy逐字节打印才定位到。 - 随机数生成:SM2 签名和密钥生成都需要强随机数。政务环境下,建议使用硬件随机数发生器,别用
rand()。嗯,别问我为什么知道。 - 密钥管理:SM4 密钥如果用 SM2 公钥加密传输,别忘了同时计算 SM3 摘要并签名。我曾经见过只传了加密的密钥,没签名,中间人可以直接替换密钥包。
核心心法:学国密算法不能光看数学公式,得把这三个算法当成“工具包”来理解。SM2 是门锁,SM3 是封条,SM4 是保险箱。政务系统里,门锁 + 封条 + 保险箱一起用,才能把数据锁得死死的。