SM2 是什么
SM2 是中国商用密码体系里的椭圆曲线公钥算法,标准为 GB/T 32918 系列:基于 256 位 SM2 曲线,包含数字签名、密钥交换与公钥加密三部分,配套摘要算法固定使用 SM3。它出现在 TLCP 传输加密、国密证书与国产密码设备中,和 ECDSA 思路相近但签名与密钥交换公式不同,两者不能互相验证。
基本信息
| 标准 | GB/T 32918.1-5 |
|---|---|
| 曲线 | 256 位,sm2p256v1 |
| 组成 | 签名(第 2 部分)、密钥交换(第 3 部分)、公钥加密(第 4 部分) |
| 配套哈希 | SM3(不用 SHA 系列) |
| 常用形式 | 签名证书与加密证书的双证书体系 |
| 典型协议 | TLCP(GB/T 38636)、部分行业专网协议 |
| 实现载体 | OpenSSL、国密网关、密码机与安全芯片 |
典型使用场景
- 国密 HTTPS:站点使用 SM2 证书配合 TLCP,浏览器或网关侧做双向验证
- 等保与密评项目:政务、金融系统按要求替换 RSA/ECDSA 体系
- 设备身份认证:安全芯片内置 SM2 引擎,用于设备入网与双向认证
- 政务专网与行业专网:终端与网关间用 SM2 签名保证报文来源
- 数据加密:小数据量场景直接用 SM2 公钥加密,大数据量走混合加密
- 密钥交换:TLCP 中作为临时密钥交换的算法,提供前向保密能力
生成密钥对与签名验签
生成密钥对与签名验签
# 先确认当前 OpenSSL 能识别 SM2 曲线名(不同版本写法可能不同)
openssl ecparam -list_curves | grep -i sm2
# 生成 SM2 密钥对(曲线名 SM2 与 sm2p256v1 在不同工具里可能等价)
openssl ecparam -name SM2 -genkey -noout -out sm2.key
openssl ec -in sm2.key -pubout -out sm2.pub
# 查看曲线与密钥长度,确认不是被换成了 P-256
openssl ec -in sm2.key -text -noout | head -6
# 摘要必须用 SM3,签名与验签参数需双方一致
openssl dgst -sm3 -sign sm2.key -out sm2.sig data.bin
openssl dgst -sm3 -verify sm2.pub -signature sm2.sig data.bin与 ECDSA 对照
| 维度 | SM2 | ECDSA |
|---|---|---|
| 标准来源 | GB/T 32918 系列 | FIPS 186-5 / SEC 1 |
| 曲线 | sm2p256v1(256 位) | P-256、P-384、P-521 等 |
| 配套哈希 | SM3 | SHA-2 系列,按曲线强度匹配 |
| 签名公式 | 与 ECDSA 不同,签名不可互验 | 行业标准实现广泛 |
| 密钥交换 | 标准内含 SM2 密钥交换流程 | 另用 ECDH(标准 NIST SP 800-56A) |
| 证书体系 | 常见双证书(签名 + 加密) | 通常单证书,由 KeyUsage 区分用途 |
TLCP 用双证书:签名证书用于握手认证,加密证书用于密钥交换。两套证书都要在有效期内、由对端信任的 CA 签发,并且算法标识写为 SM2-with-SM3。只换签名证书而忽略加密证书是最常见的配置遗漏。
曲线名写法不统一是接入时的常见摩擦:有的工具写 SM2,有的写 sm2p256v1,还有的用 OID 标识。配置前先用 openssl ecparam -list_curves 看当前版本支持的名字,跨厂商对接时以双方实测能协商为准。
接入检查清单
- 确认协议版本与套件:TLCP 的具体版本与套件双方约定一致
- 确认证书链顺序与信任根:签名证书与加密证书都要能构建完整链
- 确认摘要与签名算法标识:SM2-with-SM3 而非 SM2-with-SHA256
- 确认随机数源:签名依赖随机数 k,国密设备要使用合规的随机数模块
- 确认双证书各自用途:混用签名与加密用途会导致握手失败
- 回归测试老客户端与中间设备:国密通道的兼容性问题多出在外围设备
不要自行实现 SM2 的签名流程。签名依赖随机数 k 与曲线参数处理,实现细节出错(k 复用、曲线参数写错、点编码不一致)都会造成私钥泄漏或验签失败,且问题不会在功能测试阶段暴露。使用经过认证的密码库或硬件模块。