第1章 国密算法概述与SM2简介

说到国密算法,很多开发者的第一反应是"跟RSA差不多吧?"
嗯,我在刚接触时也这么想过。但真正深入项目之后,才发现两者差别远比想象中大。

这一章,咱们先把国密的底牌掀开看看。
我会从标准体系讲起,再深入到SM2背后的数学原理。
你不需要成为密码学专家,但搞清楚这几个核心概念,后面在云上部署SM2的时候,会少踩很多坑。

1.1 国密标准体系

国密,全称是"国家商用密码算法标准"。
说白了,就是我国自主设计的密码算法家族。
目前最核心的三个成员是:SM2、SM3、SM4。

  • SM2 —— 公钥密码算法,覆盖数字签名、密钥交换、公钥加密。对标RSA和ECDSA。
  • SM3 —— 密码杂凑算法,输出256位摘要。对标SHA-256。
  • SM4 —— 对称分组密码算法,密钥长度128位。对标AES。

我前几年做一个政务云项目时,客户明确要求"必须使用国密"。
当时团队里大部分人还是第一次接触SM2,连库怎么装都不知道。
那次之后,我就养成了一个习惯:只要涉及密码学选型,先看国标。

核心原则: 国密算法不是"替代品",而是一套独立的密码体系。
合规要求严格的场景(政府、金融、关键基础设施),必须使用国密。

下面是国密算法体系的整体结构。
我建议你存下这张图,后面讲SM2具体实现时,随时回来看一眼位置。

国密算法体系与SM2核心位置 国密标准体系 SM2 公钥密码 SM3 密码杂凑 SM4 对称密码 数字签名 密钥交换 公钥加密 电子认证 数据加密 区块链 身份认证 安全通信 SM2 是国密体系中唯一的公钥密码标准,承担数字签名、密钥协商和公钥加密三大核心职能 在云上部署时,SM2 密钥管理是合规与安全的关键环节

1.2 椭圆曲线密码学基础

SM2 的安全根基,建立在椭圆曲线离散对数问题上。
别被名字吓到——你不需要理解全部数学细节,但核心逻辑必须搞懂。

椭圆曲线的标准方程是:

y² = x³ + ax + b   (且 4a³ + 27b² ≠ 0)

说白了,就是一组满足这个方程的点(x, y),再加上一个"无穷远点",构成一个群。
在这个群上,我们可以定义"点加法"和"标量乘法"。

我给学生讲这部分时,经常用一个比喻:
椭圆曲线上的点加法,就像钟表上的时针走动——每次加一个固定步长,最终落在某个位置。想从结果反推加了多少步,非常困难。这就是离散对数问题的难处。

为什么这个性质对密码学有用?
因为"已知起点和步数,容易算出终点"(正向运算快),但"已知起点和终点,几乎不可能反推出步数"(逆向运算难)。
这个"步数"就是私钥,"终点"就是公钥。

我的经验: 刚开始学椭圆曲线时,别死磕代数几何。先记住"标量乘法正向快、逆向难"这个性质,后面理解签名和密钥交换会顺很多。

SM2 使用的是哪条曲线?
它采用了国家推荐的 sm2p256v1 曲线,参数是固定的。
这一点和比特币的 secp256k1 类似——所有参与者用同一条曲线,互操作性才有保障。

1.3 SM2算法详解

SM2 不是一个单一的算法,而是一族算法。
它包含三个核心组件:数字签名、密钥交换和公钥加密。

组件 功能 对标国际算法 典型应用
数字签名 签名生成与验签 ECDSA 电子合同、身份认证
密钥交换 双方协商会话密钥 ECDH TLS握手、安全信道
公钥加密 用公钥加密数据 ECIES 密文传输、密钥分发

这里重点说一下数字签名的流程,因为后续在云上部署时会频繁用到:

  1. 初始化: 生成密钥对(私钥 d,公钥 P = d·G)
  2. 签名: 对消息的哈希值,用私钥 d 和随机数 k 计算签名值 (r, s)
  3. 验签: 接收方用公钥 P 验证 (r, s) 是否与消息匹配

用 Python 实现 SM2 签名,其实已经有好用的库了。我个人推荐 gmssl,封装得比较干净:

from gmssl import sm2, func

# 生成随机私钥(十六进制字符串)
private_key = func.random_hex(32)
public_key = sm2.CryptSM2(private_key=private_key).get_pubkey()

# 初始化 SM2 签名对象
sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)

# 签名
msg = b"Hello, SM2"
random_hex = func.random_hex(32)
sign = sm2_crypt.sign(msg, random_hex)

# 验签
is_valid = sm2_crypt.verify(sign, msg)
print("验签结果:", is_valid)  # True
避坑指南: 签名时使用的随机数 k 不能重复!
我曾经在测试环境中用固定随机数做压力测试,结果导致多组签名中泄露了私钥。
后来排查了整整两天才找到原因——随机数重用是 SM2 的致命伤。

1.4 SM2 vs RSA:优势与适用场景

很多人问我:既然 RSA 用得那么广泛,为什么还要换 SM2?
我一般回答:不是换,而是升。

SM2 相比 RSA,有几个明显的优势:

  • 密钥更短,安全等级更高: SM2 的 256 位密钥即可达到 RSA 3072 位的安全强度。
  • 运算速度更快: 签名和密钥协商的性能远优于 RSA,尤其是在移动端和物联网设备上。
  • 算法设计更现代: 基于椭圆曲线,天然支持签名、加密、密钥交换三种模式,一套体系搞定。
  • 合规强制要求: 在中国政企和金融领域,国密是强制标准,没有替代选项。

但 RSA 也有它的存量优势:

  • 现有基础设施中 RSA 证书的兼容性最好,国际 CA 普遍支持。
  • RSA 的加解密性能在短数据场景下依然够用。
  • 迁移成本:全栈切换到 SM2,需要改造代码、替换证书、升级网关。
对比维度 SM2 (256位) RSA (3072位)
密钥长度 256 bit 3072 bit
签名速度 约 3000 次/秒 约 200 次/秒
验签速度 约 800 次/秒 约 8000 次/秒
安全强度 128 位安全级 128 位安全级
合规认可 国标强制 国际通用
选型建议: 新项目首选 SM2,尤其是面向政务、金融、运营商等需要合规的场景。
存量系统可以逐步做"双证书支持"过渡,先让 SM2 与 RSA 并行,再择机切换。