1. SM2 算法概述:国密标准背景、椭圆曲线原理与 RSA/ECC 对比

各位同学,咱们今天开篇聊 SM2。说实话,搞了这么多年密码学工程,SM2 是我个人觉得「最值得投入时间吃透」的国密算法之一。为什么?因为它不光是标准,更是咱们在 TEE 里做安全沙箱部署的基石。你想想看,没有这个基础,后面那些隔离、签名、密钥协商全都没法落地。

1.1 国密标准背景:为什么要有 SM2?

先说说背景。2010 年,国家密码管理局正式发布了 SM2 椭圆曲线公钥密码算法系列标准。说白了,就是咱们要有自己的密码体系,不能总依赖国外的 RSA 或 ECDSA。我在 2015 年参与过一个政务云项目,当时客户明确要求「必须全栈国密」,从 TLS 握手到数据签名,全部换成 SM2/SM3/SM4。嗯,那是我第一次真正在工程里大规模部署 SM2,踩了不少坑,但也积累了很多实战经验。

SM2 算法族包含三个核心部分:

  • 数字签名算法 —— 用于身份认证和完整性校验
  • 密钥交换协议 —— 用于双方安全协商会话密钥
  • 公钥加密算法 —— 用于数据加密传输

这三个部分在 TEE 沙箱里各有用途。比如签名用来验证 TA 的合法性,密钥交换用来建立安全通道,公钥加密用来保护敏感数据。我建议你先把这三个场景记在脑子里,后面每一章都会反复用到。

核心要点:SM2 不是单一算法,而是一套完整的公钥密码体系。在 TEE 部署中,签名和密钥交换用得最多,加密次之。

1.2 SM2 椭圆曲线密码算法原理

椭圆曲线密码,说白了就是利用椭圆曲线上的点群运算来做加密。SM2 使用的是基于素数域 Fp 上的椭圆曲线,参数由国家指定。我个人习惯把椭圆曲线理解成「一个特殊的加法游戏」—— 你可以在曲线上做点加、点倍,然后利用这些运算构造出单向函数。

SM2 的曲线参数(p, a, b, G, n, h)都是公开的,其中:

  • p —— 素数模数,256 位
  • a, b —— 曲线方程 y² = x³ + ax + b 中的系数
  • G —— 基点,生成整个循环群
  • n —— 基点 G 的阶,素数
  • h —— 余因子,通常为 1

SM2 的密钥对生成非常简单:

私钥 d: 随机选取 [1, n-2] 之间的整数
公钥 P: P = d * G  (椭圆曲线上的标量乘法)

这里有个关键点:从公钥 P 反推私钥 d,就是椭圆曲线离散对数问题(ECDLP),目前没有多项式时间解法。这就是安全性的根基。我记得有一次做安全审计,对方问「SM2 的 256 位密钥相当于 RSA 多少位?」我直接回答:大概相当于 RSA 3072 位的安全强度。后面我会详细对比。

实战小技巧:在 TEE 环境中生成 SM2 密钥对时,一定要确保随机数生成器(TRNG)的质量。我曾经遇到过因为熵源不足导致私钥可预测的案例,那真是血的教训。

SM2 的签名算法流程(简化版)如下:

  1. 计算消息哈希值 e = SM3(Z || M),其中 Z 是用户身份标识
  2. 生成随机数 k ∈ [1, n-1]
  3. 计算椭圆曲线点 (x₁, y₁) = k * G
  4. 计算 r = (e + x₁) mod n,若 r=0 或 r+k=n 则重试
  5. 计算 s = ((1 + d)⁻¹ * (k - r * d)) mod n,若 s=0 则重试
  6. 输出签名 (r, s)

验签就是反过来,用公钥 P 验证 (r, s) 是否匹配。这里要注意,SM2 的签名过程比 ECDSA 多了一个「用户身份标识 Z」的参与,这是国标特有的设计,目的是防止密钥被滥用。

1.3 SM2 与 RSA/ECC 的对比分析

咱们直接上表格,这样最清楚。我做了这么多年密码工程,对比表是最实用的参考工具。

对比维度 SM2 RSA ECC(如 secp256k1)
算法基础 椭圆曲线离散对数 大整数分解 椭圆曲线离散对数
密钥长度 256 位 2048~4096 位 256 位
安全强度 ≈ RSA 3072 位 2048 位(中等) ≈ RSA 3072 位
签名速度 快(约 1~2ms) 慢(约 5~10ms) 快(约 1~2ms)
验签速度 快(约 2~3ms) 快(约 0.5ms) 快(约 2~3ms)
密钥生成 极快 慢 极快
国密合规 是 否 否
TEE 适配性 优(原生支持) 一般(需大数库) 良(需移植)

从表格可以看出,SM2 在密钥长度和签名速度上优势明显。RSA 虽然验签快,但密钥太长,在 TEE 这种资源受限环境里很不友好。至于 ECC(比如比特币用的 secp256k1),虽然数学原理和 SM2 类似,但曲线参数不同,而且不满足国密合规要求。

避坑指南:千万不要在国密项目里直接用 OpenSSL 的 ECC 实现然后改个参数就号称「SM2 兼容」。我曾经见过一个项目,开发人员直接把 secp256k1 的曲线参数换成 SM2 的 p、a、b,结果签名验签全失败。SM2 的签名算法流程和 ECDSA 有本质区别,必须用国标规定的完整实现。

为什么 SM2 更适合 TEE 沙箱?我总结三点:

  • 密钥短 —— 256 位公钥在安全存储区里只占 32 字节,非常适合 TEE 的受限内存
  • 运算快 —— 椭圆曲线运算在 ARM TrustZone 或 Intel SGX 里都有硬件加速指令
  • 原生支持 —— 主流 TEE 平台(如 ARM TrustZone、Intel SGX、AMD SEV)都已原生支持 SM2 指令集

下面这张图是我自己整理的 SM2 在 TEE 沙箱中的核心定位,你可以直观看到它和 TEE 各组件的关系。

SM2 在 TEE 安全沙箱中的核心定位 TEE 安全沙箱边界 SM2 密码引擎 签名 / 密钥交换 / 加密 私钥 (d) 安全存储区 公钥 (P) 共享内存区 消息/哈希 REE 传入 签名 (r, s) 返回 REE 会话密钥 安全通道 密文 加密输出 SM2 引擎在 TEE 内部完成所有私钥操作,公钥和消息可从 REE 传入,签名/密钥/密文输出到 REE

从这张图你可以看到,SM2 引擎位于 TEE 沙箱的核心位置。私钥永远不出 TEE,公钥和消息可以从普通世界(REE)传入,签名结果或密文再返回给 REE。这种架构保证了私钥的绝对安全,也是后面我们做沙箱部署的核心原则。

个人经验:我在部署 SM2 到 TEE 时,最常犯的错误是「密钥生命周期管理」。很多人只关注算法实现,却忘了私钥的生成、存储、销毁流程。记住:算法再强,密钥泄露就全完了。后面我会专门用一章讲 TEE 里的密钥管理最佳实践。