4. TLS 1.3 密钥交换:ECDHE 密钥交换原理、前向安全性、密钥协商过程、临时密钥生成
4.1 ECDHE 密钥交换原理
ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)是 TLS 1.3 中唯一的密钥交换算法(传统 RSA 密钥交换已被移除)。它结合了椭圆曲线密码学(ECC)的高效性与临时密钥的“一次一密”特性,是 TLS 1.3 安全性的核心支柱。
ECDHE 基于椭圆曲线上的离散对数难题(ECDLP):给定基点 G 和公钥 Q = d·G,求私钥 d 在计算上不可行。双方通过交换临时公钥,各自计算共享秘密,而窃听者无法从公开信道中恢复该秘密。
核心优势: 相比传统 DHE,ECDHE 在同等安全强度下密钥长度更短(256 位 ECC 约等于 3072 位 RSA/DH),计算速度更快,带宽占用更低。
4.2 前向安全性(Perfect Forward Secrecy, PFS)
前向安全性是 TLS 1.3 的强制性要求。其核心思想是:即使服务器长期私钥泄露,也无法解密之前记录的会话流量。
| 特性 | RSA 密钥交换(TLS 1.2 及之前) | ECDHE 密钥交换(TLS 1.3) |
|---|---|---|
| 会话密钥生成方式 | 客户端生成 Pre-Master Secret,用服务器 RSA 公钥加密传输 | 双方通过 ECDHE 临时密钥对独立计算共享秘密 |
| 长期私钥作用 | 用于解密 Pre-Master Secret,直接暴露会话密钥 | 仅用于签名认证,不参与密钥派生 |
| 长期私钥泄露后果 | 所有历史会话均可被解密 | 历史会话安全,无法解密 |
| 前向安全性 | ❌ 不支持 | ✅ 强制支持 |
关键理解: 在 ECDHE 中,服务器长期私钥只用于对 ECDHE 临时公钥进行数字签名(证明该公钥确实来自该服务器),而从不参与会话密钥的计算。因此,即使攻击者获取了服务器私钥,也只能伪造身份,无法解密已记录的会话流量。
4.3 密钥协商过程(TLS 1.3 完整握手)
TLS 1.3 将握手压缩为 1-RTT(往返时间),密钥协商与证书认证并行进行。以下是完整的 ECDHE 密钥协商流程:
- ClientHello: 客户端发送支持的密码套件列表、随机数
client_random,以及 ECDHE 临时公钥client_share(包含曲线类型和公钥值)。 - ServerHello: 服务器选择密码套件,发送随机数
server_random,以及 ECDHE 临时公钥server_share。 - EncryptedExtensions + Certificate + CertificateVerify: 服务器发送证书链,并用长期私钥对握手消息签名(包含双方的 ECDHE 公钥),证明身份。
- 密钥派生: 双方使用 ECDHE 计算共享秘密
shared_secret,再通过 HKDF(HMAC-based Key Derivation Function)派生出会话密钥。 - Finished: 双方发送握手消息的 MAC,验证握手完整性。
4.4 临时密钥生成
临时密钥(Ephemeral Key)是 ECDHE 实现前向安全性的关键。每次 TLS 握手都会生成全新的临时密钥对,握手结束后立即销毁私钥。
4.4.1 密钥生成步骤
- 选择曲线: TLS 1.3 强制支持
secp256r1(P-256)和X25519(Curve25519)。推荐优先使用 X25519,因其实现更安全、性能更优。 - 生成临时密钥对: 使用安全的随机数生成器(CSPRNG)产生私钥
d(256 位随机数),计算公钥Q = d·G。 - 编码与传输: 公钥以未压缩格式(x,y 坐标)或 X25519 的 32 字节标量形式编码,放入 KeyShareEntry 结构中传输。
- 计算共享秘密: 收到对方公钥后,使用自己的私钥执行标量乘法:
shared_secret = d_own · Q_peer。
安全实践: 临时私钥必须使用操作系统提供的安全随机数生成器(如 Linux 的
/dev/urandom),且使用后应立即从内存中擦除(zeroize),防止侧信道攻击或内存转储泄露。
4.4.2 密钥派生(HKDF)
ECDHE 计算出的共享秘密是一个椭圆曲线上的点,不能直接用作对称密钥。TLS 1.3 使用 HKDF(RFC 5869)进行密钥派生:
// 伪代码:TLS 1.3 密钥派生流程
// 输入:shared_secret (ECDHE 输出), client_random, server_random
// 输出:handshake_traffic_secret, application_traffic_secret
// 第1步:提取(Extract)
early_secret = HKDF-Extract(salt=0, ikm=PSK) // 无 PSK 时 salt=0
handshake_secret = HKDF-Extract(salt=early_secret, ikm=shared_secret)
// 第2步:扩展(Expand)
client_handshake_traffic_secret = HKDF-Expand-Label(
handshake_secret, "c hs traffic", client_random + server_random, 32)
server_handshake_traffic_secret = HKDF-Expand-Label(
handshake_secret, "s hs traffic", client_random + server_random, 32)
// 第3步:派生应用层密钥
master_secret = HKDF-Extract(salt=handshake_secret, ikm=0)
client_application_traffic_secret = HKDF-Expand-Label(
master_secret, "c ap traffic", client_random + server_random, 32)
server_application_traffic_secret = HKDF-Expand-Label(
master_secret, "s ap traffic", client_random + server_random, 32)
4.4.3 曲线对比
| 曲线 | 密钥长度 | 安全强度 | 性能 | TLS 1.3 支持 |
|---|---|---|---|---|
| secp256r1 (P-256) | 256 位 | 128 位 | 中等(需验证点是否在曲线上) | ✅ 强制 |
| X25519 (Curve25519) | 256 位 | 128 位 | 高(常数时间实现,无专利限制) | ✅ 推荐 |
| secp384r1 (P-384) | 384 位 | 192 位 | 较低 | ✅ 可选 |
总结: ECDHE 通过临时密钥对 + 椭圆曲线密码学,实现了 TLS 1.3 的强制前向安全性。每次握手独立生成密钥,长期私钥仅用于签名认证,确保即使未来私钥泄露,历史会话依然安全。HKDF 的提取-扩展结构保证了密钥的随机性和独立性,是 TLS 1.3 安全架构的基石。