2、会话密钥基础:对称加密与非对称加密、密钥交换协议(Diffie‑Hellman、RSA)、完美前向保密(PFS)概念

聊 TLS 之前,得先把“会话密钥”这块地基打扎实。到底什么是会话密钥?说白了,就是一次 TLS 握手期间临时生成的对称密钥,只对当前连接有效。你想想看,如果每次通信都用同一个固定密钥,那一旦泄露,所有历史记录都完蛋。

我过去做金融支付网关的时候,就因为没搞懂对称与非对称的配合,踩过一个大坑。后来才彻底明白——TLS 是拿非对称加密来保护对称密钥的交换,再拿对称加密来保护真正的业务数据。缺一不可。

对称加密 vs 非对称加密

这两种算法,一个快,一个安全。怎么选?看场景。

维度对称加密非对称加密
密钥数量双方共享同一个密钥一对密钥:公钥+私钥
计算速度极快(硬件加速友好)慢(几百到几千倍差距)
典型算法AES、ChaCha20RSA、ECDSA
密钥分发困难(需要安全通道)公钥可以公开传递
使用场景批量数据加密密钥交换、数字签名

对称加密的效率高,但密钥怎么安全地发给对方?这就是非对称加密登场的地方。

我习惯把非对称加密比作一个信箱:公钥是锁,谁都能往里塞信;私钥是钥匙,只有你有。把对称密钥用公钥加密发给对方,只有对方用私钥能解开。这个思路,就是 TLS 握手最核心的设计。

密钥交换协议:Diffie‑Hellman 与 RSA

常用的两种交换方式:RSA 密钥交换和 Diffie‑Hellman(DH)密钥协商。

RSA 密钥交换

客户端生成一个随机对称密钥,然后用服务器的 RSA 公钥加密发送过去。服务器用私钥解密拿到密钥。

  • 优点:简单,一步到位。
  • 缺点:如果私钥泄露,攻击者可以解密所有历史会话。嗯,这很致命。
避坑指南:我曾经在维护一套老系统时,发现它一直用 RSA 密钥交换。当时客户要求追溯半年前的某个交易记录,结果服务器私钥刚好被运维误删重签过……历史流量全解密不了。所以从那以后,我对 RSA 交换方式总是多个心眼。

Diffie‑Hellman(DH)密钥协商

双方不直接传输密钥,而是各自生成临时私钥,通过公开参数计算出一个共享秘密。即使攻击者拿到所有公开值,也推不出最终的协商密钥。

它的数学基础是离散对数问题(我们不用展开公式,记住结论就好)。

  • 缺点:性能不如 RSA 快(非对称运算次数多)。
  • 优点:临时密钥每次都在变化,服务器私钥泄露不会影响历史会话——这就引出了完美前向保密。

现代 TLS 推荐使用 ECDHE(椭圆曲线版 DH),性能比普通 DH 好得多。

完美前向保密(PFS)

PFS 是一个属性:即使服务器或客户端的长期私钥泄露,之前所有会话的密钥仍然安全。

为什么?因为每次会话的临时密钥都是独立生成的,和长期私钥没有直接关系。DH 或 ECDHE 正好满足这个要求。

而 RSA 密钥交换呢?临时密钥直接拿长期公钥加密,一旦私钥泄露,所有历史会话都裸奔。

一句话记牢:启用 PFS = 使用基于 DH 的密钥交换(ECDHE/DHE),禁止纯 RSA 交换。

我在审计一个电商平台的 TLS 配置时,发现他们用了 TLS 1.2 但 cipher suite 里没有 ECDHE,还在用 RSA。我跟他们说“赶紧加 PFS,否则每次私钥轮换都会让历史记录变成安全隐患”。他们改完之后,安全评审才通过。

实际做法:在 nginx 配置里优先选带 ECDHE 的 cipher suite,比如 ECDHE-ECDSA-AES128-GCM-SHA256。丢掉 TLS_RSA_WITH_AES_128_GCM_SHA256 这类纯 RSA 套件。

三者关系一张图

下面这张图展示了对称加密、非对称加密、密钥交换与 PFS 之间的关系。我画它的时候,把 TLS 握手简化为三个核心动作:身份认证(非对称)、密钥协商(DH)、数据保护(对称)。

TLS 会话密钥体系 ① 身份认证(非对称) RSA / ECDSA 证书验证 ② 密钥协商(DH/ECDHE) 临时私钥 + 公开参数 → 共享秘密 ③ 数据加密(对称) AES / ChaCha20 加密应用数据 最终产出:会话密钥(临时对称密钥) 完美前向保密(PFS) • 服务器长期私钥泄露 → 历史会话密钥依然安全 • 必要条件:使用 DH/ECDHE 协商,不能只用 RSA 直接加密密钥 • 副作用:每次握手需要临时密钥对,性能损耗约 10%~20%(ECDHE 可接受) 红框 = 易错点:若不启用 ECDHE,则无 PFS

小结

  • 对称加密负责快,非对称加密负责安全传输临时密钥。
  • DH/ECDHE 实现密钥协商,天生支持 PFS。
  • 纯 RSA 交换虽然简单,但不提供 PFS,不建议在新系统里用。

我的经验:每次配置 TLS 时,先问自己一句——“如果私钥今天泄露,昨天的会话记录还安全吗?” 答案是肯定的,就对了。答案是“不确定”,赶紧检查 cipher suite 里有没有 ECDHE。