1. 简介
1. 简介 (Introduction)
在 TLS [RFC5246] 中, 每个会话都有一个 master_secret, 其计算方式如下:
master_secret = PRF(pre_master_secret, "master secret",
ClientHello.random + ServerHello.random)
[0..47];
其中 pre_master_secret 是某种密钥交换协议的结果. 例如, 当握手使用 RSA ciphersuite 时, 该值由客户端均匀随机生成; 而对于 Ephemeral Diffie-Hellman (DHE) ciphersuites, 它是 Diffie-Hellman 密钥协商的结果.
如 [TRIPLE-HS] 所述, 在 RSA 和 DHE 密钥交换中, 主动攻击者都可以同步两个 TLS 会话, 使它们共享同一个 master_secret. 对于客户端未认证的 RSA 密钥交换, 可按如下方式实现. 假设客户端 C 连接到服务器 A. C 没有意识到 A 是恶意的, 也没有意识到 A 在后台连接到诚实服务器 S 并完成两个握手. 为简单起见, 假设 C 和 S 只使用 RSA ciphersuites.
-
C 向 A 发送
ClientHello, A 将其转发给 S. -
S 向 A 发送
ServerHello, A 将其转发给 C. -
S 向 A 发送包含其证书链的
Certificate. A 将其替换为自己的证书链并发送给 C. -
S 向 A 发送
ServerHelloDone, A 将其转发给 C. -
C 向 A 发送
ClientKeyExchange, 其中包含使用 A 公钥加密的pre_master_secret. A 解密pre_master_secret, 再用 S 的公钥重新加密, 然后发送给 S. -
C 向 A 发送
Finished. A 为其与 S 的连接计算Finished并发送给 S. -
S 向 A 发送
Finished. A 为其与 C 的连接计算Finished并发送给 C.
此时, 两个连接, 即 C 与 A 之间以及 A 与 S 之间的连接, 都有了新会话, 并共享相同的 pre_master_secret, ClientHello.random, ServerHello.random, 以及其他会话参数, 包括 session identifier 和可选的 session ticket. 因此, 两个会话的 master_secret 值将相等, 并且在 C 和 S 处都与同一个 session ID 关联, 即使两个连接上的服务器身份不同. 回想一下, C 只看到 A 的证书, 并不知道 A 与 S 的连接. 此外, 两个连接上的 record keys 也会相同.
上述场景表明, TLS 并不保证不同连接上使用的 master secrets 和 keys 一定不同. 即使使用客户端认证, 该场景仍然成立, 只是此时两个会话在客户端身份和服务器身份上都不同.
当握手使用 DHE ciphersuite 时, 也可以实现类似场景. 请注意, 即使客户端或服务器不偏好使用 RSA 或 DHE, 攻击者也可以通过在 hello messages 中只提供 RSA 或 DHE 来迫使它们使用. 使用 Ephemeral Elliptic Curve Diffie-Hellman (ECDHE) ciphersuites 的握手, 如果允许任意 explicit curves 或使用带有小子群的曲线, 也容易受到攻击. 面对更强大的对手, 其他密钥交换, 例如 Secure Remote Password (SRP) 和 Pre-Shared Key (PSK), 也已被证明存在脆弱性 [VERIFIED-BINDINGS].
一旦 A 同步了两个连接, 由于两侧密钥相同, 它就可以离开协议路径并透明转发 C 与 S 之间的消息, 在需要时读取和修改消息. 在密钥交换文献中, 这种情况称为 unknown key-share attacks, 因为 C 和 S 共享一个秘密, 但二者都认为自己的秘密只与 A 共享. 这类攻击本身不会破坏诚实方之间的完整性或机密性, 但它们为针对 C 和 S 发起 impersonation attacks 提供了有用起点.
假设 C 试图在与 A 的新连接上恢复其会话. A 随后可以在与 S 的新连接上恢复其会话, 并在 C 与 S 之间原样转发 abbreviated handshake messages. 由于 abbreviated handshake 只依赖 master secret 进行认证, 并不提及客户端或服务器身份, 两个握手都会成功完成, 产生相同的 session keys 和相同的 handshake log. A 仍然知道连接密钥, 并可以向 C 和 S 发送消息.
关键在于, 在新连接上, 即使 handshake log 在 C 和 S 上也相同. 这会击败任何依赖 finished messages 唯一性的 man-in-the-middle 保护方案, 例如 secure renegotiation indication extension [RFC5746] 或 TLS channel bindings [RFC5929]. [TRIPLE-HS] 描述了多种基于这种会话同步攻击的利用方式. 特别是, 它描述了一种称为 "triple handshake" 的 man-in-the-middle attack, 该攻击绕过 [RFC5746] 的保护, 在 session resumption 之后破坏客户端认证的 TLS renegotiation. 类似攻击也适用于依赖 channel bindings [RFC5929] 或依赖从 TLS 导出的 key material [RFC5705] 的应用层认证机制.
导致这些攻击的底层协议问题是, TLS master secret 不保证跨会话唯一, 因为它没有与生成它的完整握手上下文绑定. 如果在初始 master secret 计算中修复这一问题, 则可以防止所有这些攻击. 本规范引入一个 TLS 扩展, 通过包含握手消息日志来改变 full handshake 中 master_secret 值的计算方式, 从而使不同会话按构造拥有不同的 master secrets. 这可以防止 [TRIPLE-HS] 中描述的攻击, 以及 [RFC7457] 第 2.11 节中记录的攻击.