SM2 算法概述:椭圆曲线密码学背景、SM2 标准简介

好,咱们直接切入正题。这一章我会带你快速捋一遍 SM2 的背景和核心概念。为什么要有椭圆曲线?SM2 到底好在哪?别急,我一边讲一边加点实战里的坑。

1.1 椭圆曲线密码学(ECC)的由来

说白了,密码学里搞公钥加密,第一代是 RSA。RSA 靠的是大整数分解的难度。但你想想,随着算力提升,RSA 的密钥长度越拉越长——2048 位、4096 位…… 算起来慢,存起来也费劲。

椭圆曲线密码学(Elliptic Curve Cryptography,ECC)就不一样。它走的是一条“瘦”路子——用更短的密钥,实现同等级别的安全强度。256 位的 ECC 密钥,差不多顶得上 3072 位的 RSA。资源受限的场景,比如智能卡、物联网,ECC 就是首选。

💡 个人印象:我记得刚接触密码学时,觉得椭圆曲线特别“玄学”。后来在一个身份认证项目里,硬是拿 256 位曲线把 RSA 2048 位的握手时间压掉了 60%。那之后我就彻底倒向 ECC 了。

1.2 椭圆曲线的数学基础(快速回顾)

椭圆曲线不是椭圆函数,别搞混了。它的标准方程是:

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

这个曲线上的点,加上一个无穷远点 O,构成一个阿贝尔群。有两个运算特别关键:

  • 点加法:给两个点 P、Q,画一条直线穿过它们(必要时考虑切线),再取第三个交点并关于 x 轴对称,得到 R = P + Q。
  • 标量乘法:k·P = P + P + … + P(k 次)。从 P 出发,计算 k·P 很容易,但知道 k·P 和 P 反推 k —— 这就是椭圆曲线离散对数问题(ECDLP)。它比整数分解还难对付。

嗯,这里要注意:你实际产线上用的不是实数域上的曲线,而是有限域上的。比如素域 Fp 或二元域 F2m。咱们 SM2 用的是素数域 Fp。

域类型特点SM2 选用
Fp(素域)运算速度快,硬件友好✓ 国标推荐
F2m(二元域)适合某些专用硬件可选但少用

1.3 SM2 标准体系

SM2 是我国发布的椭圆曲线公钥密码算法标准,全称《SM2 椭圆曲线公钥密码算法》。里面包含三个子算法:

  • 数字签名算法(SM2-DSA)—— 用于身份验证、防篡改。
  • 密钥交换协议(SM2-KEP)—— 咱们这门课的主角,后续章节会深挖。
  • 公钥加密算法(SM2-PKE)—— 实现数据加密传输。

你想想看,一个标准统一了签名、加密、密钥协商三个域,多方便。我在项目中遇到过用国密改造 HTTPS 的场景,直接把 SM2 的数字签名和密钥交换嵌进 TLS 握手层,整个适配工作比预想顺利得多。

⚠️ 避坑指南:我曾经被 SM2 的密钥对生成搞晕过——SM2 的公钥必须包含两个坐标(x, y),长度 64 字节;但有些实现只传 x 坐标然后隐式推导 y,这会导致协商时验签失败。所以做密钥交换时,强烈建议用 SM2 标准定义的完整公钥格式。

1.4 国密 SM2 与标准 ECC 的主要差异

既然 SM2 是基于 ECC 的,那你可能想问:它跟常见的 ECDSA、ECDH 有啥区别?我列个表,一目了然:

对比项SM2ECDSA / ECDH
曲线参数国标固定一条 256 位素域曲线(sm2p256v1)多种曲线可选(P-256, secp256k1 等)
签名算法基于 SM3 哈希,哈希长度 256 位SHA-2/SHA-3 系列
密钥交换双向身份认证+会话密钥生成ECDH 仅协商密钥,不强制做身份认证
加密方式混合加密(KDF + 对称加密)ECIES 类似,具体细节不同

说白了,SM2 把国产密码算法(SM3、SM4)也整合进来了,形成了一个闭环。如果你做的项目有“自主可控”要求,那选 SM2 就是顺理成章的事。我去年做一个政务云项目,客户点名要 SM2,就是因为合规性。

1.5 本章知识结构图

我把这一章的核心知识画了一张图。你可以看到 ECC 是地基,SM2 标准是上层建筑,而密钥交换就是其中一堵承重墙。后续章节的任务就是“砌好这堵墙”。

第一章知识体系:从 ECC 到 SM2 标准 椭圆曲线密码学 数学基础(离散对数) 素域 Fp 曲线 密钥长度优势 SM2 公钥密码算法标准 SM2-DSA(数字签名) SM2-KEP(密钥交换) SM2-PKE(公钥加密) 本课程重点研究 ▸ 密钥交换协议(第3章起)

1.6 本章小结 & 避坑提醒

这一章我们走完了从 ECC 到 SM2 的认知路径:

  • ECC 用更短的密钥提供同等安全强度,是 SM2 的数学基石。
  • SM2 标准涵盖签名、加密、密钥交换,三者共用同一套曲线参数。
  • 与标准 ECDSA/ECDH 相比,SM2 多了国产哈希(SM3)和双向身份认证。
⚠️ 我曾经踩过的坑:有次在调试 SM2 密钥交换时,发现双方计算出的会话密钥不一致。查了半天,问题出在曲线参数上——一方用了国标推荐的曲线(sm2p256v1),另一方却误用了 secp256k1。两个曲线名字看着像,但阶完全不同。从那以后我养成了一个习惯:代码里显式写出曲线 OID(1.2.156.10197.1.301),绝不靠默认值。