# 2. 国密算法标准概述:SM2、SM3、SM4、SM9

隐私增强SDK国密算法适配指南 - 第2节

2.1 国密算法的四块基石

说到国密算法,很多开发者第一反应就是“SM打头的那几个”。没错,SM2、SM3、SM4、SM9 就是国密体系的四大支柱。我在项目里跟它们打了多年交道,说白了,这四兄弟各有分工,谁也替不了谁。

核心认知:国密算法不是单一算法,而是一整套密码学工具链。SM2管非对称,SM3管哈希,SM4管对称加密,SM9管基于身份的密码体系。

2.2 SM2 — 椭圆曲线公钥密码算法

SM2 是我最早接触的国密算法。那是2015年,一个政务云项目要求全线替换RSA。我一开始觉得麻烦,后来发现 SM2 在性能上其实不输 RSA 2048,甚至在某些场景下更优。

2.2.1 算法核心参数

参数项SM2 取值备注
椭圆曲线y² = x³ + ax + b素数域 256 位
密钥长度公钥 64 字节
私钥 32 字节
比 RSA 2048 小得多
签名长度64 字节r + s 各 32 字节
安全强度128 位等效 AES-128

2.2.2 SM2 的三个核心功能

  • 数字签名:我习惯用 SM2 做签名验签。一次签名生成 64 字节,比 RSA 2048 的 256 字节轻量很多。在 IoT 设备上,这个差距太明显了。
  • 公钥加密:加密后的密文比原文多 64 字节左右。你想想看,如果每次加密的数据量不大,这个开销完全可以接受。
  • 密钥交换:双方通过 SM2 协商出对称密钥。我在做端到端加密时特别喜欢用这个功能。
个人技巧:SM2 签名验签我建议用 C1C3C2 格式存储密文。这是国密标准推荐的顺序,能跟硬件密码模块无缝对接。
我曾经踩过的坑:在一台老旧 ARM 设备上,SM2 点运算因为缺少硬件加速,一次签名耗时超过 200ms。后来我改用预计算窗口法优化,降到 30ms。所以啊,嵌入式环境一定要提前做性能评估。

2.3 SM3 — 密码杂凑算法

SM3 说白了就是个国标版的 SHA-256。它的输出是固定的 256 位(32 字节),用在完整性校验、数字签名、密钥派生这些地方。我记得有个项目,需要把文件 hash 上传到区块链做存证,SM3 用得很顺手。

2.3.1 SM3 与 SHA-256 的对比

属性SM3SHA-256
输出长度256 位256 位
消息分组512 位512 位
压缩函数轮数64 轮64 轮
初始向量自定义 IV自定义 IV
安全强度128 位抗碰撞128 位抗碰撞

其实两者的性能差距很小。我个人做基准测试时发现,SM3 在 x86 平台上比 SHA-256 慢大概 10%~15%。但在国产芯片上,SM3 经常有硬件加速,反而更快。

常见应用场景:
  • 文件完整性校验(类似 MD5,但更安全)
  • 数字签名中的消息摘要
  • 密钥派生函数 KDF
  • 随机数生成

2.4 SM4 — 分组对称加密算法

SM4 是我每天都在用的国密算法。它是分组加密,密钥长度 128 位,分组大小也是 128 位。为什么会强调这个?因为 SM4 的设计目标就是轻量高效,特别适合嵌入式环境。

2.4.1 SM4 的密码学特性

  • 结构:Feistel 网络结构,32 轮迭代。Feistel 的好处是加密和解密过程几乎一样,代码复用度高。
  • S 盒:国标定义了一套 S 盒,抗线性分析和差分分析能力很强。
  • 密钥扩展:固定 128 位密钥扩展到 32 个轮密钥。比 AES 的密钥扩展简单不少。

2.4.2 工作模式选择

嗯,这里要注意。SM4 本身只定义了基本分组加密,实际使用必须搭配工作模式。我见过有人直接用 ECB 模式,那真是现场翻车。

模式推荐场景为什么不推荐 ECB
CBC通用数据加密需要 IV 随机性保证
GCM需要认证加密的场景SM4-GCM 需要额外实现
CTR流式加密、并行计算ECB 相同明文块产生相同密文
我调试过一个项目:对方直接用 SM4-ECB 加密 JSON 数据,结果加密后长度不变,攻击者一眼就能看出哪些字段是重复的。改成 SM4-CBC 后问题解决。所以千万记住:ECB 只适合加密随机密钥,别用在常规数据上。

2.5 SM9 — 基于标识的密码算法

SM9 比起前三个算法,概念上新鲜不少。它是基于标识的密码体系(Identity-Based Cryptography, IBC)。你想想看,用一个人的邮箱、手机号就能当公钥用,不用再折腾证书、CA、CRL 那一套了。

2.5.1 SM9 的核心思想

SM9 依赖双线性对(也叫配对运算)。用户标识直接作为公钥,私钥由密钥生成中心(KGC)颁发。我在项目中做密钥托管时就用 SM9,省去了证书管理的麻烦。

2.5.2 SM9 的应用场景

  • 加密通信:发送方直接用接收方的标识加密,接收方从 KGC 获取私钥后解密。
  • 签名验签:签名时用私钥,验签时用对方标识即可。
  • 密钥协商:双方通过标识和 KGC 公开参数协商出会话密钥。
SM9 vs SM2 的核心区别:
SM2 需要先拿到对方的公钥证书,验证证书链,然后才能用公钥。SM9 直接拿对方标识(比如手机号)就能加密。也就是说,SM9 天然解决了公钥分发的问题。
我记得第一次在 Kubernetes 里配 SM9:Pod 之间的通信直接用 ServiceAccount 名称作为标识,省去了证书挂载的步骤。一个字,爽。

2.6 四种算法的关系总览

我画了一张图来帮大家从整体上理解这四种算法的位置和关系。你看完应该能记住哪个场景该用谁。

国密算法体系总览 SM2 非对称 加密/解密 签名/验签 SM3 杂凑 完整性校验 SM4 对称 数据加密 VPN/SSL SM9 标识密码 无证书加密 密钥协商 SM3 为签名和完整性提供摘要,SM2/SM4 管加解密,SM9 省去证书管理 四者组合即为完整的国密安全方案

2.7 在隐私增强 SDK 中的选型建议

你在设计隐私增强 SDK 时,怎么选这些算法?我给出一些经验之谈。

2.7.1 匿名化场景

数据脱敏、匿名化处理时,SM3 做 hash 加盐是最常见的方案。但注意,SM3 是确定性哈希,不能直接用于需要不可逆的强匿名场景。我一般会在 SM3 前加随机盐和计数器。

2.7.2 加密存储和传输

  • 对称加密:首选 SM4-CBC 或 SM4-GCM。
  • 密钥分发:用 SM2 或 SM9 做密钥封装。
  • 完整性校验:SM3 生成哈希值。

2.7.3 属性加密和细粒度访问控制

SM9 的标识特性天然适合基于属性的加密(类似 CP-ABE,但不完全相同)。我在联邦学习项目中,用 SM9 对模型梯度做加密,接收方不再需要维护证书列表,标识即公钥。

快速记忆口诀:
SM2 做签名,SM3 来摘要,
SM4 管加密,SM9 不依赖证书。

2.8 实践中的适配要点

说一千道一万,最后还是要落地。我在适配过程中吃过亏,这里列几条硬教训:

  • SM2 签名数据格式:标准规定签名输出是 DER 编码的 ASN.1 结构。如果你的 SDK 对接的是 Java 的 Bouncy Castle,它会自动处理成 DER;如果是 C 语言裸写,记得自己编码。
  • SM4 密钥长度:必须是 128 位(16 字节)。别问我为什么有人传 256 位进去,我修过这种 bug。
  • SM9 双线性对效率:双线性对运算比普通椭圆曲线慢一个数量级。在做 SM9 密钥协商时,单次配对大约 5~10ms(看平台)。不要在高频短连接场景下大量使用。
  • 算法标识 OID:国密标准给每个算法定义了 OID。SM2 是 1.2.156.10197.1.301,SM3 是 1.2.156.10197.1.401,SM4 是 1.2.156.10197.1.104。在证书和协议字段中要用对。
最后提醒一句:国密算法的实现必须符合 GM/T 系列标准。不要为了性能去改 S 盒、改参数、改模式。标准化的意义就在于互通性。你改了,其他厂商的设备和软件就解不开了。