4 非对称加密算法:RSA、ECC、SM2 的原理与密钥对管理

4.1 非对称加密的「一锁双钥」逻辑

说白了,非对称加密就是一把锁配两把钥匙——公钥拿来上锁,私钥才能打开。我在银行做密钥管理系统时,经常跟业务方解释:公钥像你家的门牌号,谁都能看到;私钥是你口袋里的钥匙,丢了就完了。

这套机制的核心依赖数学难题。RSA靠大整数分解,ECC和SM2靠椭圆曲线离散对数。破解难度决定了密钥长度:RSA要2048位,ECC/SM2用256位就能达到同等安全强度。你想想看,少存那么多字节,在嵌入式设备里有多香。

4.2 RSA 原理与密钥对生成

RSA是我最早接触的非对称算法。它的数学基础很简单:找两个大素数p和q,算n=p×q,再找一个e和d使得e×d≡1 mod φ(n)。公钥就是(e,n),私钥就是(d,n)或者(d,p,q)。

密钥生成步骤

  1. 选两个长度相当的大素数p、q(比如1024位)。
  2. 计算n=p×q,φ(n)=(p-1)(q-1)。
  3. 选一个公钥指数e,通常用65537(0x10001),好算又安全。
  4. 用扩展欧几里得算法求私钥d ≡ e⁻¹ mod φ(n)。
  5. 输出公钥(e,n),私钥(d,n)或CRT格式(p,q,dP,dQ,qInv)。
重点:p和q不能太接近,否则RSA能被费马分解法快速攻破。我见过一个系统直接调用OpenSSL的RSA_generate_key_ex,没检查素数距离,后来被安全审计发现,吓得赶紧重写了一版。

加解密与签名验签

操作公式说明
加密c = m^e mod nm必须小于n,且不能是p或q的倍数
解密m = c^d mod n用私钥还原明文
签名s = hash(m)^d mod n先对消息哈希再签名
验签hash(m) == s^e mod n验证签名是否匹配
RSA加密有填充方案,别直接用课本的原始公式。PKCS#1 v1.5或OAEP必须加,否则你加密相同明文会得到相同密文,这跟明文传输没区别。我踩过这个坑,后来老老实实用了OAEP。

4.3 ECC 原理与密钥对管理

椭圆曲线密码学用了一个不同的数学坑——椭圆曲线上的离散对数问题。给定基点G和点Q=kG,求k很难。这跟RSA比,优势就是短。

我习惯把ECC私钥比喻成一个超大整数k,公钥就是一个曲线上的点Q。生成密钥对时,只需随机选k ∈ [1,n-1],算Q=kG,完事。

ECC 关键参数

  • 曲线方程:y² = x³ + ax + b,常用secp256k1(比特币那条)或P-256
  • 基点G:公开的生成元
  • 阶n:G的循环子群阶,一般是大素数
  • 余因子h:n除以椭圆曲线点群阶的比值,通常为1
# 用Python演示ECC密钥生成(简化)
import secrets
# 假设曲线参数已知
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141  # secp256k1的阶
k = secrets.randbelow(n)  # 私钥
print(f"私钥: {hex(k)}")
# 公钥Q = k * G,需要调用椭圆曲线点乘库
ECC私钥必须真随机生成,别用弱随机数种子。我曾经见过一个路由器固件,私钥用系统时间做种子,结果同一秒内所有设备生成了相同的密钥对,黑客可以预计算公钥直接登录。教训深刻。

4.4 SM2:国标椭圆曲线

SM2是我国发布的椭圆曲线公钥密码算法,标准号GM/T 0003-2012。它跟ECC同属一类,但细节有差异。

SM2 与 ECC 的关键区别

项目国际ECC(如P-256)SM2
曲线参数secp256r1等sm2p256v1(p=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF)
签名算法ECDSASM2签名(与ECDSA不同,先算哈希再映射到曲线点)
密钥长度256位256位
国家支持通用国密标准,境内商用必须用

SM2的密钥对生成跟ECC基本一致:选随机数d∈[1,n-2]作为私钥,计算公钥P=[d]G。但SM2的签名校验公式更复杂,它把消息哈希和随机点结合,防止某些旁路攻击。

如果你的系统需要过国密局检测,乖乖用SM2。我帮一家政务云迁移时,原系统用ECDSA签名,被要求整改成SM2。好在密钥对管理逻辑几乎一样,只换了曲线库和签名接口。记得把算法OID也改了。

4.5 密钥对管理全生命周期

算法是枪,管理是保险栓。我见过太多安全事件不是算法被破解,而是密钥泄露或管理混乱。下面这张图概括了密钥对管理的关键阶段。

非对称密钥对生命周期管理 非对称密钥对生命周期管理 1. 密钥生成 RSA 2048/ECC 256/SM2 2. 分发/部署 公钥公开,私钥安全传输 3. 使用/签名 加解密/签名验签 4. 安全存储 HSM/密钥管理服务 5. 密钥轮换 定期/事件触发 6. 销毁/退役 安全擦除/撤销证书 下线存放 轮换触发新密钥生成 关键管理原则 • 私钥绝不能离开HSM/安全元件,签名在内部完成 • 轮换周期一般1~2年,密码事件后立即轮换 • 销毁时必须覆盖内存/磁盘,不能只删文件 • 公钥可以明文存储,但需要证书链防篡改

密钥生成黄金准则

  • 硬件随机数源:服务器用Intel RDRAND或内核熵池,嵌入式用TRNG。
  • 公私钥长度:RSA至少2048位,ECC/SM2至少256位。我建议新系统直接上RSA 4096或ECC 384,不差那点性能,多几年寿命。
  • 生成一次,不再修改:私钥一旦生成,不要增量更新,那跟重新生成没区别,还容易引入漏洞。

安全存储方案

存储介质适用场景安全等级
HSM(硬件安全模块)CA根密钥、支付系统极高(物理防篡改)
TPM(可信平台模块)PC/服务器本地密钥高(无法导出私钥)
KMS(密钥管理服务)云原生应用中高(依赖云厂商防护)
加密文件+密码开发测试环境低(仅限非生产)
千万别把私钥放在代码仓库或配置文件里。我审计过一个项目,.git仓库里躺着一个pem文件,注释写着「临时测试用」,结果这个密钥被扫描工具扒出来,直接导致整个AWS账号被入侵。从那以后,我在所有团队加了gitignore规则和密钥嗅探钩子。

4.6 避坑与经验

讲几个我亲自踩过的坑,希望你别走老路。

  • RSA填充攻击:曾经用原始教科书RSA实验,加密同一明文两次得到相同密文,被甲方安全工程师当场指出。后来用OAEP填充,加了随机盐,一切正常。
  • ECC曲线选择:不要用自己写的曲线参数!我见过一个创业公司用自创曲线,结果离散对数问题被特殊方法破解。只用NIST/SECG/国密标准曲线。
  • SM2签名与ECDSA混用:SM2签名过程需要先将消息哈希转成椭圆曲线点,再与私钥运算。如果直接用ECDSA的接口,验签必失败。记得用国密标准的签名接口。
  • 密钥轮换漏掉备份:轮换后旧私钥必须保留一段时间的验证能力,直到所有依赖方更新。我一般设一个grace period,比如30天,再彻底销毁。

4.7 小结

非对称加密是密钥边界设计的基石。RSA胜在通用,ECC/SM2赢在短小。选型时别只看算法强度,还要看生态支持、合规要求和密钥管理成本。我个人建议:新系统首选ECC(P-256或X25519),国内商用必选SM2。密钥对管理遵循生命周期自动化原则——生成、存储、轮换、销毁都能用工具链跑起来,别靠人肉操作。