2. 国密算法基础:SM2、SM3、SM4
各位同学,咱们今天聊聊国密算法的三大支柱。说实话,我在做安全启动方案时,最常打交道的就这三个算法:SM2、SM3、SM4。它们分别对应了公钥密码、哈希函数和对称密码,缺一个都不行。
你想想看,一个完整的嵌入式安全启动流程,需要签名验签、完整性校验、数据加密解密。这三个算法正好各司其职。我个人习惯把这三者比作“钥匙、指纹、保险箱”——SM2是钥匙,SM3是指纹,SM4是保险箱。下面咱们一个一个拆开讲。
2.1 SM2:椭圆曲线公钥密码算法
SM2 是国密标准中的公钥密码算法,基于椭圆曲线密码学(ECC)。说白了,它跟国际上的 ECDSA、ECDH 是同类,但曲线参数是咱们自己定义的。
我记得第一次在嵌入式芯片上移植 SM2 时,踩了个大坑——椭圆曲线点乘运算太慢了。后来发现是模逆运算没优化好。嗯,这里要注意,SM2 的推荐曲线是 256 位的素域曲线,参数如下:
| 参数 | 值 | 说明 |
|---|---|---|
| p | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF | 素域模数 |
| a | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC | 曲线系数 |
| b | 28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93 | 曲线系数 |
| n | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123 | 基点阶 |
| Gx | 32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7 | 基点 x 坐标 |
| Gy | BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0 | 基点 y 坐标 |
SM2 的核心操作包括:密钥生成、签名、验签、加密、解密。在安全启动场景中,我们最常用的是签名和验签。流程大致是这样的:
- 密钥生成: 随机选取私钥 d,计算公钥 P = d * G
- 签名: 对消息 M 的哈希值进行签名,输出 (r, s) 对
- 验签: 用公钥 P 验证 (r, s) 是否匹配消息 M
2.2 SM3:密码杂凑算法
SM3 是国密标准的哈希算法,输出 256 位摘要。它的设计思路跟 SHA-256 类似,但消息扩展和压缩函数有自己的一套。
我个人觉得 SM3 最值得关注的是它的消息扩展部分——它将 16 个字的消息扩展成 68 个字,再用 64 轮压缩函数处理。这种设计让 SM3 的抗碰撞能力很强。
SM3 的算法流程可以概括为:
输入:消息 M(任意长度)
输出:256 位摘要值
1. 消息填充:在 M 末尾补 1 和若干个 0,最后 64 位放原始长度
2. 分组处理:每 512 位(16 个字)为一组
3. 消息扩展:16 个字 → 68 个字(W0~W67)+ 64 个字(W'0~W'63)
4. 压缩函数:64 轮迭代,每轮用 Wj 和 W'j 更新 8 个状态字
5. 输出:8 个状态字拼接成 256 位摘要
在安全启动中,SM3 的典型用途是计算固件镜像的哈希值。比如,我们先把整个固件镜像用 SM3 算一遍,得到一个 256 位的摘要,然后用 SM2 对这个摘要签名。启动时,BootROM 先算镜像的 SM3 摘要,再用 SM2 验签。这样就能保证固件没有被篡改过。
2.3 SM4:分组密码算法
SM4 是国密标准的对称分组密码算法,分组长度 128 位,密钥长度 128 位。它采用 32 轮 Feistel 结构,每轮用一个 32 位的轮密钥。
说实话,SM4 的设计很精巧。它的 S 盒只有 256 个元素,但非线性度很高。密钥扩展算法也很有意思——它用跟加密相同的结构来生成轮密钥,只是常数不同。
SM4 的加密流程:
输入:128 位明文 (X0, X1, X2, X3)
输出:128 位密文 (Y0, Y1, Y2, Y3)
1. 密钥扩展:128 位密钥 → 32 个 32 位轮密钥 (rk0~rk31)
2. 32 轮迭代:
for i = 0 to 31:
Xi+4 = Xi XOR T(Xi+1 XOR Xi+2 XOR Xi+3 XOR rki)
3. 反序变换:
(Y0, Y1, Y2, Y3) = (X35, X34, X33, X32)
在安全启动中,SM4 通常用于加密固件镜像。比如,固件在工厂烧录时用 SM4 加密,启动时 BootROM 用预置的密钥解密。这样即使有人读出了 Flash 里的数据,也拿不到明文固件。
| 工作模式 | 适用场景 | 注意事项 |
|---|---|---|
| ECB | 单块数据加密 | 相同明文块产生相同密文块,不推荐用于固件加密 |
| CBC | 固件镜像加密 | 需要 IV,IV 可以放在固件头部 |
| CTR | 流式加密 | 可以并行计算,适合高性能场景 |
| GCM | 加密+认证 | 同时提供机密性和完整性,推荐用于安全启动 |
2.4 三种算法的协同关系
好了,三个算法都讲完了。你可能会问:安全启动中它们怎么配合?
我画个简单的流程:
- 固件打包阶段: 用 SM3 计算固件镜像的摘要 → 用 SM2 私钥对摘要签名 → 用 SM4 加密固件镜像
- 启动验证阶段: BootROM 用 SM4 解密固件 → 用 SM3 计算解密后固件的摘要 → 用 SM2 公钥验签
这个流程中,SM3 保证完整性,SM2 保证真实性,SM4 保证机密性。三者缺一不可。
嗯,这一章的内容就到这里。记住这三个算法的核心参数和适用场景,后面讲安全启动架构时,我们会反复用到它们。