4. 非对称加密基础:RSA、ECC算法原理与适用场景
咱们做字段级加密,绕不开一个核心问题——密钥怎么分配?对称加密速度快,可密钥得提前商量好,放到生产环境里,密钥分发简直就是噩梦。我刚开始做支付系统时,就因为把对称密钥硬编码在配置里,被安全审计逮个正着……从那之后,非对称加密就成了我的护身符。
说白了,非对称加密就是公钥加密、私钥解密。公钥随便公开,私钥自己藏好。你加密时用对方的公钥,只有对方用私钥才能解开。这背后的数学原理,主要就两个流派:RSA 和 ECC。咱们一个一个拆开看。
4.1 RSA:大整数分解的硬骨头
RSA 是 1977 年三位大佬(Rivest、Shamir、Adleman)搞出来的。它的核心数学难题是:两个大素数相乘很容易,但把一个很大的合数分解成素数极其困难。嗯,就是这条路。
RSA 的工作流程可以分成三步:
1. 选两个大素数 p、q,计算 n = p × q。
2. 计算欧拉函数 φ(n) = (p-1)(q-1),选一个 e(通常 65537),且 e 与 φ(n) 互质。
3. 算私钥 d:d × e ≡ 1 (mod φ(n))。
加密时:c = me mod n(m 是明文整数)。
解密时:m = cd mod n。
注意哦,这里 m 必须小于 n。实际使用时,我们通常用 RSA 加密一个对称密钥(比如 AES 的密钥),再用对称密钥加密真正的数据。这就是混合加密——性能和安全两不误。
| RSA 参数 | 说明 | 典型取值 |
|---|---|---|
| n(模数) | 两个大素数的乘积 | 2048 位、4096 位 |
| e(公钥指数) | 常用固定值 | 65537 |
| d(私钥指数) | 由 e 和 φ(n) 计算得出 | 与 n 同量级 |
| p、q(素数) | 随机生成,长度约为 n 的一半 | 1024 位/2048 位 |
4.2 ECC:椭圆曲线上的离散对数难题
ECC 的全称是 Elliptic Curve Cryptography。它的数学基础是:椭圆曲线上两点相加得到第三点,已知基点和倍点,求倍数的离散对数问题很难。你想想看,这就是「单向函数」的另一种实现。
ECC 最大的优点是:密钥更短,安全强度更高。256 位 ECC 密钥的安全性和 3072 位 RSA 相当。这对节省带宽和存储空间很有利,尤其是在移动端或 IoT 设备上。
椭圆曲线方程长这样:y² = x³ + ax + b(且 4a³ + 27b² ≠ 0)。设基点 G,私钥 d(一个随机整数),公钥 Q = d × G(椭圆曲线上的点加法运算)。加密过程比 RSA 复杂一些,一般用 ECIES(Elliptic Curve Integrated Encryption Scheme)或 ECDH 做密钥协商。
我个人习惯用曲线 secp256k1 或 P-256。 前者是区块链上的默认曲线(比特币用的),后者是 NIST 推荐的标准。注意:如果你的应用中需要 FIPS 认证,选 P-256(也叫 prime256v1)。
4.3 RSA vs ECC:谁更香?
咱们直接上对比表格,一目了然:
| 对比项 | RSA | ECC |
|---|---|---|
| 安全基础 | 大整数分解 | 椭圆曲线离散对数 |
| 密钥长度(等安全) | 2048 位 | 224~256 位 |
| 加解密速度 | 慢(尤其是私钥操作) | 快(比 RSA 快 10~50 倍) |
| 签名验证速度 | 中等 | 更快(特别是签名) |
| 密钥生成 | 慢(需要找大素数) | 极快(随机数 + 点乘) |
| 性能特点 | 加密运算快于解密 | 解密/签名快于加密 |
| 标准规范 | PKCS#1、OAEP 等 | SEC 1、NIST SP 800-56A |
| 量子抗性 | 无(Shor 算法可破解) | 无(同样被 Shor 破解) |
你问我选哪个?如果你做的是字段级加密里对「少量数据」的加密(比如加密一个对称密钥),RSA 够用了;如果数据量大或对性能敏感,ECC 更合适。 不过一定要注意:别把 RSA 的 n 和 ECC 的私钥混起来比,它们本质不同。
4.4 适用场景总结
- 密钥交换 / 密钥封装:RSA-OAEP 或 ECIES,用来加密对称密钥。
- 数字签名:RSA PKCS#1 v1.5 或 PSS,ECDSA(ECC 签名)。签名性能 ECDSA 更好。
- 身份认证:公钥证书(X.509)里常用 RSA 或 ECC。
- 字段级加密(直接加密敏感字段):一般不直接用非对称加密整个字段,因为非对称加密速度慢、密文尺寸大。通常的做法是:
a. 生成一个临时对称密钥(比如 AES-256),用 RSA/ECC 公钥加密这个临时密钥。
b. 用临时密钥加密字段数据(对称加密)。
c. 存储时保存密文 + 加密后的临时密钥(即密文信封)。
我曾在项目中处理医保卡号加密:每个用户不同临时密钥,RSA 加密临时密钥,AES 加密卡号。这样一来,即使数据库泄漏,没有私钥谁也解不开。
4.5 避坑指南:填充模式与曲线选择
- RSA 填充不能省:直接裸加密(教科书式 RSA)是脆弱的,必须用 OAEP(推荐)或 PKCS#1 v1.5(已被发现弱点)。我曾经接手过一个项目,他们做了 RSA 加密却没加填充,被 CTR 攻击打穿……
- ECC 曲线别用自定义:只使用标准命名曲线。NIST P-256、P-384、secp256k1、Curve25519(X25519)都是经过验证的。自己造曲线=找死。
- 密钥长度与安全等级对照:
| 安全等级 (bits) | RSA 长度 | ECC 长度 |
|---|---|---|
| 80 | 1024 | 160 |
| 112 | 2048 | 224 |
| 128 | 3072 | 256 |
| 192 | 7680 | 384 |
| 256 | 15360 | 512 |