3. 非对称加密基础:公钥密码体系、RSA算法原理、ECC椭圆曲线、密钥交换(Diffie-Hellman)
好,咱们今天聊聊非对称加密。说实话,我刚入行那会儿,总觉得对称加密够用了——又快又简单。直到有一次做项目,需要和第三方安全地交换密钥,我才发现对称加密有个死穴:密钥怎么安全地传给对方?
你想想看,如果密钥在传输过程中被截获,那加密就形同虚设。这就是非对称加密要解决的问题。它用一对密钥:公钥公开,私钥自己藏好。别人用你的公钥加密,只有你能用私钥解密。反过来,你用私钥签名,别人用公钥验证。
3.1 公钥密码体系
公钥密码体系的核心思想,说白了就是「单向陷门函数」。什么意思?正向计算很容易,反向推导极难。但如果你知道一个秘密(陷门),反向就变得简单。
我举个例子:你把两个大素数乘在一起,几毫秒就搞定。但给你一个大合数,让你分解成两个素数?嗯,现代计算机算到宇宙毁灭可能都算不出来。这就是单向性。而那个「陷门」就是你知道的其中一个素数。
- 加密:用公钥加密,只有私钥能解密
- 数字签名:用私钥签名,公钥验证身份
- 密钥交换:双方在不安全的信道上协商出共享密钥
我在项目中遇到过最典型的场景:客户端和服务端建立连接时,客户端用服务端的公钥加密一个临时对称密钥,然后双方用这个对称密钥进行后续通信。这样既解决了密钥分发问题,又保留了对称加密的高效性。
3.2 RSA算法原理
RSA 是 1977 年由 Rivest、Shamir 和 Adleman 三位大佬提出的。它至今仍是应用最广泛的非对称加密算法之一。它的安全性基于大整数分解的困难性。
RSA 密钥生成步骤:
- 随机选择两个大素数 p 和 q(通常 1024 位以上)
- 计算 n = p × q(n 就是公钥的一部分)
- 计算欧拉函数 φ(n) = (p-1)(q-1)
- 选择一个整数 e,满足 1 < e < φ(n),且 e 与 φ(n) 互质(常用 e = 65537)
- 计算 d,使得 e × d ≡ 1 (mod φ(n))(d 就是私钥)
公钥就是 (n, e),私钥就是 (n, d)。p 和 q 必须销毁或妥善保管。
加密和解密:
加密:c = m^e mod n
解密:m = c^d mod n
这里 m 是明文,c 是密文。你可能会问:为什么解密能还原?因为根据欧拉定理,m^(e×d) ≡ m (mod n)。数学就是这么奇妙。
- p 和 q 不能太接近,否则容易被费马分解法攻破
- 不要直接用 RSA 加密大量数据,效率太低。一般用 RSA 加密对称密钥,再用对称加密处理数据
- 填充方案很重要!直接用教科书 RSA 容易受到选择密文攻击。建议用 OAEP 填充
3.3 ECC椭圆曲线
ECC(Elliptic Curve Cryptography)是后来居上的选手。它的优势在于:同等安全强度下,密钥长度更短。
| 安全强度(位) | RSA 密钥长度 | ECC 密钥长度 |
|---|---|---|
| 80 | 1024 | 160 |
| 112 | 2048 | 224 |
| 128 | 3072 | 256 |
| 256 | 15360 | 512 |
你看,256 位的 ECC 密钥就能达到 15360 位 RSA 的安全强度。这意味着更少的计算量、更小的存储空间、更快的传输速度。我在做物联网项目时,设备资源有限,ECC 几乎是唯一的选择。
ECC 的数学基础:
椭圆曲线方程一般形式:y² = x³ + ax + b。在密码学中,我们用的是有限域上的椭圆曲线,所有点构成一个阿贝尔群。
核心操作是「点乘」:k × P = P + P + ... + P(k 次)。给定 k 和 P,计算 k×P 很容易。但给定 P 和 Q = k×P,求 k 就非常困难——这就是椭圆曲线离散对数问题(ECDLP)。
- 优先使用标准曲线,如 secp256r1(P-256)、Curve25519
- 不要自己实现 ECC 算法,用 OpenSSL、Bouncy Castle 等成熟库
- 注意检查点是否在曲线上,防止无效曲线攻击
3.4 密钥交换(Diffie-Hellman)
Diffie-Hellman 密钥交换(简称 DH)是 1976 年由 Whitfield Diffie 和 Martin Hellman 提出的。它解决了一个看似不可能的问题:两个人在公开信道上如何协商出一个只有他们知道的共享密钥?
DH 协议流程:
- 双方约定一个大素数 p 和一个生成元 g(公开的)
- Alice 随机选择私钥 a,计算 A = g^a mod p,发送 A 给 Bob
- Bob 随机选择私钥 b,计算 B = g^b mod p,发送 B 给 Alice
- Alice 计算共享密钥 K = B^a mod p = g^(b×a) mod p
- Bob 计算共享密钥 K = A^b mod p = g^(a×b) mod p
你看,双方算出来的 K 是一样的。而窃听者只知道 p、g、A、B,要算出 K 就必须解离散对数问题——这在计算上是不可行的。
- DHE(临时 DH):每次会话生成新的临时密钥对,提供前向安全性
- ECDH:基于椭圆曲线的 DH,效率更高
- 中间人攻击:经典 DH 不验证身份,需要结合数字签名或证书
我记得有一次做安全审计,发现某个系统用了静态 DH——每次连接都用相同的密钥对。这意味着一旦私钥泄露,所有历史通信都能被解密。后来我建议他们改用 DHE,虽然每次握手多了一点计算量,但安全性提升了一个档次。
3.5 实际应用中的选择
说了这么多,到底该用哪个?我个人习惯这样选:
- 需要兼容老旧系统:用 RSA(2048 位以上)
- 资源受限设备:用 ECC(P-256 或 Curve25519)
- 密钥交换:用 ECDHE(椭圆曲线临时 DH)
- 数字签名:用 ECDSA 或 EdDSA
嗯,这里要注意:没有银弹。每种算法都有适用场景。关键是要理解它们的原理和局限,才能做出合理的设计决策。
非对称加密解决了密钥分发问题,但牺牲了效率。实际系统中,通常用非对称加密做密钥交换和身份认证,用对称加密做数据加密。两者配合,才是最佳实践。