2. Protocol Overview (协议概述)
安全信道使用的密码参数由 TLS handshake protocol 产生. client 和 server 初次通信时使用该 TLS 子协议. handshake protocol 允许 peer 协商 protocol version, 选择 cryptographic algorithm, 可选地相互认证, 并建立共享 secret keying material. 握手完成后, peer 使用已建立的 key 保护 application-layer traffic.
handshake 失败或其他 protocol error 会触发 connection 终止, 终止前可以发送 alert message (第 6 节).
TLS 支持三种基本 key exchange mode:
- (EC)DHE: 基于有限域或椭圆曲线的 Diffie-Hellman.
- PSK-only.
- PSK with (EC)DHE.
完整 TLS handshake 可以分为三个阶段:
- Key Exchange (密钥交换): 建立共享 keying material 并选择密码参数. 此阶段之后的所有内容都会加密.
- Server Parameters (服务器参数): 建立其他 handshake 参数, 例如是否认证 client, application-layer protocol 支持等.
- Authentication (认证): 认证 server, 可选认证 client, 并提供 key confirmation 和 handshake integrity.
在 Key Exchange 阶段, client 发送 ClientHello (第 4.1.2 节). 该消息包含随机 nonce, 提供的 protocol version, symmetric cipher/HKDF hash pair 列表, "key_share" extension 中的 Diffie-Hellman key share 集合, "pre_shared_key" extension 中的 pre-shared key label 集合, 或两者兼有, 还可能包含其他 extension. 为了中间盒兼容性, 也可能存在额外字段或消息.
server 处理 ClientHello 并确定 connection 的适当密码参数, 然后以 ServerHello (第 4.1.3 节) 响应, 指示协商出的 connection parameter. ClientHello 与 ServerHello 的组合决定 shared key. 如果使用 (EC)DHE key establishment, ServerHello 包含 "key_share" extension, 其中有 server 的 ephemeral Diffie-Hellman share. server share MUST 与 client 提供的某个 share 位于同一 group. 如果使用 PSK key establishment, ServerHello 包含 "pre_shared_key" extension, 指示选择了 client 提供的哪个 PSK. 实现可以同时使用 (EC)DHE 和 PSK, 此时会提供两个 extension.
随后 server 发送用于建立 Server Parameters 的消息:
- EncryptedExtensions: 对不需要用于确定密码参数的 ClientHello extension 的响应, 但特定于单个 certificate 的 extension 除外.
- CertificateRequest: 如果需要基于 certificate 的 client authentication, 该消息携带所需 certificate 参数. 如果不需要 client authentication, 则省略该消息.
最后, client 和 server 交换 Authentication message. TLS 在需要基于 certificate 的认证时始终使用同一组消息. 基于 PSK 的认证则作为 key exchange 的副作用发生:
- Certificate: endpoint 的 certificate 及 per-certificate extension. 如果 server 不使用 certificate 认证, 或 client 未收到 CertificateRequest, 则省略该消息. 使用 raw public key [RFC7250] 或 cached information extension [RFC7924] 时, 该消息可能不包含 certificate, 而是包含对应于 server long-term key 的其他值.
- CertificateVerify: 使用 Certificate 消息中 public key 对应的 private key, 对整个 handshake 进行签名. 如果 endpoint 不通过 certificate 认证, 则省略该消息.
- Finished: 对整个 handshake 的 MAC. 该消息提供 key confirmation, 将 endpoint identity 绑定到交换出的 key, 并在 PSK mode 中认证 handshake.
收到 server 消息后, client 以自己的 Authentication message 响应, 即在需要时发送 Certificate 和 CertificateVerify, 并发送 Finished.
此时 handshake 完成, client 和 server 派生 record layer 所需的 keying material, 用 authenticated encryption 保护 application-layer data. 除第 2.3 节规定的情况外, 在发送 Finished 之前 MUST NOT 发送 Application Data. 注意, server 可以在收到 client Authentication message 之前发送 Application Data, 但此时数据当然是发送给尚未认证的 peer.
2.1 Incorrect DHE Share (错误 DHE 份额)
如果 client 没有提供足够的 "key_share" extension, 例如只包含 server 不接受或不支持的 DHE/ECDHE group, server 会通过 HelloRetryRequest 纠正不匹配, client 需要带合适的 "key_share" extension 重新开始 handshake. 如果无法协商出公共密码参数, server MUST 使用适当 alert 中止 handshake.
handshake transcript 包含初始 ClientHello/HelloRetryRequest 交换, 不会随新的 ClientHello 重置.
TLS 也允许若干基本 handshake 的优化变体.
2.2 Resumption and Pre-Shared Key (PSK) (恢复和预共享密钥)
TLS PSK 可以在带外建立, 也可以在先前 connection 中建立, 然后用于建立新 connection, 即通过 PSK 进行 session resumption. 一次 handshake 完成后, server 可以向 client 发送一个 PSK identity, 它对应从初始 handshake 派生出的唯一 key. client 之后可以在未来 handshake 中使用该 PSK identity 协商相关 PSK 的使用. 如果 server 接受 PSK, 新 connection 的安全上下文会在密码学上绑定到原始 connection, 并使用从初始 handshake 派生出的 key 来引导密码状态, 而不是执行完整 handshake.
在 TLS 1.2 及更早版本中, 该功能由 "session ID" 和 "session ticket" [RFC5077] 提供. TLS 1.3 废弃这两种机制.
PSK 可与 (EC)DHE key exchange 结合使用, 以在共享 key 的基础上提供 forward secrecy. PSK 也可以单独使用, 代价是 application data 失去 forward secrecy.
server 通过 PSK 认证时, 不发送 Certificate 或 CertificateVerify 消息. client 通过 PSK 提供 resumption 时, SHOULD 同时向 server 提供 "key_share" extension, 以便 server 在需要时拒绝 resumption 并回退到完整 handshake. server 使用 "pre_shared_key" extension 协商 PSK key establishment, 并可以用 "key_share" extension 执行 (EC)DHE key establishment, 从而提供 forward secrecy.
如果 PSK 是带外配置的, 也 MUST 配置 PSK identity 以及与 PSK 一起使用的 KDF hash algorithm.
带外配置 pre-shared secret 时, 关键考虑是 key generation 需要足够熵, 如 [RFC4086] 所述. 从 password 或其他低熵来源派生 shared secret 并不安全. 低熵 secret 或 password 会受到基于 PSK binder 的 dictionary attack. 即使与 Diffie-Hellman key establishment 一起使用, 这里规定的 PSK authentication 也不是强 password-based authenticated key exchange. 具体而言, 它不能阻止能观察 handshake 的攻击者对 password/pre-shared-key 执行 brute-force attack.
2.3 0-RTT Data
当 client 和 server 共享 PSK 时, 无论 PSK 是外部获得还是通过先前 handshake 获得, TLS 1.3 允许 client 在第一轮 flight 中发送数据, 即 "early data". client 使用 PSK 认证 server 并加密 early data.
0-RTT data 的安全属性弱于其他 TLS data:
- 该数据不具备 forward secrecy, 因为它只使用由所提供 PSK 派生出的 key 加密.
- connection 之间没有 non-replay 保证. 普通 TLS 1.3 1-RTT data 通过 server Random 值提供重放防护, 但 0-RTT data 不依赖 ServerHello, 因而保证更弱. 如果数据通过 TLS client authentication 或应用协议内部完成认证, 这一点尤其相关. 同样警告也适用于 early_exporter_master_secret 的任何使用.
0-RTT data 不能在同一 connection 内被复制, 即 server 不会对同一 connection 处理相同数据两次. 攻击者也不能使 0-RTT data 看起来像 1-RTT data, 因为二者使用不同 key 保护. Appendix E.5 描述潜在攻击, 第 8 节描述 server 可用于限制 replay 影响的机制.