非对称加密算法详解:RSA、ECC、SM2

非对称加密,说白了就是两把钥匙——公钥公开,私钥藏好。我从做第一个支付项目时就深有体会:对称加密虽然快,但密钥分发太头疼。后来换了RSA,才松了口气。不过现在ECC和SM2也越来越流行,今天我把这三个算法拉到一起对比着讲。

RSA:大整数分解的经典

数学基础:两个大质数相乘容易,但反过来分解极难。RSA正是利用这个非对称性。

  • 密钥生成:
    1. 随机选两个大质数 p、q(比如2048位)
    2. 计算 n = p × q,φ(n) = (p-1)(q-1)
    3. 选公钥指数 e(常用65537),满足 1 < e < φ(n) 且 gcd(e, φ(n))=1
    4. 计算私钥 d ≡ e⁻¹ mod φ(n)
  • 加解密:c = m^e mod n,m = c^d mod n

安全强度:1024位已不安全,2048位建议用,4096位更稳。我曾经在合规审计中被要求把1024位证书全部替换,那工作量真不小。

ECC:椭圆曲线的后起之秀

ECC为什么会火?同样的安全强度下,它的密钥长度比RSA短得多。你想想看,256位ECC ≈ 3072位RSA。

  • 数学基础:椭圆曲线 y² = x³ + ax + b 上的点加法构成循环群,离散对数难解。
  • 密钥生成:
    1. 选一条曲线(如secp256r1)和基点 G
    2. 随机选私钥 k(1 < k < 阶)
    3. 公钥 Q = k × G(标量乘法)

技巧:ECC标量乘法用双倍加法实现,性能优化时可预计算窗口。我在嵌入式设备上做过优化,密钥生成比RSA快一个数量级。

SM2:国密标准必须懂

SM2本质也是ECC,但曲线参数和签名算法都是国标。做政务项目时,我遇到过强制要求使用SM2的场合。

  • 曲线特点:256位素数域,基点和阶固定。
  • 密钥生成:与ECC类似,但使用GB/T 32918规定参数。
  • 安全强度:256位SM2 ≈ 3072位RSA,且抗量子能力略优于RSA。

对比表格:一张图看清

维度 RSA ECC SM2
数学问题 大整数分解 椭圆曲线离散对数 椭圆曲线离散对数
密钥长度(同等安全) 2048位 256位 256位
加解密速度 慢(指数运算) 快(点运算) 快(点运算)
签名速度 中等 快 快
国际标准 PKCS#1 SEC1/X9.62 GB/T 32918

避坑指南

我曾经踩过一个坑:用RSA加密时,明文长度不能超过密钥长度减11字节(因为填充)。一次项目上线前才发现密文串被截断了,紧急改了分段加密逻辑。嗯,这里要注意。

核心逻辑图:三种算法关系

非对称加密算法核心逻辑 非对称加密 RSA ECC SM2 (国密) 大数分解 密钥长 椭圆曲线离散对数 密钥短、速度快 国标ECC变体 合规必选 数字证书、加密传输 移动端、区块链 政务、金融 安全强度:RSA-2048 ≈ ECC-256 ≈ SM2-256

代码示例:RSA密钥生成(Python)

from Crypto.PublicKey import RSA

# 我习惯用2048位,平衡安全与性能
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
print("私钥长度:", len(private_key))
print("公钥长度:", len(public_key))

ECC密钥生成(Python)

from ecdsa import SECP256k1, SigningKey

sk = SigningKey.generate(curve=SECP256k1)
vk = sk.verifying_key
print("私钥(hex):", sk.to_string().hex())
print("公钥(hex):", vk.to_string().hex())

提示:生产环境中不要用自己实现的曲线,直接用openssl或成熟库。我曾经见过一个项目用自定义曲线,结果参数选错了导致安全漏洞,后来全部重写。

好了,三种算法从数学到密钥生成都过了一遍。记住:选哪个要看场景——RSA兼容性好,ECC性能优,SM2合规强。我自己的做法是:新系统优先ECC,对接政务必须SM2,老系统保留RSA过渡。