RFC 6347 - 3. DTLS 概述 (Overview of DTLS)
3. Overview of DTLS (DTLS 概述)
DTLS 的基本设计理念是构建 "基于数据报传输的 TLS (TLS over datagram transport)"。TLS 无法直接用于数据报环境的简单原因是分组可能丢失或重排。TLS 没有处理此类不可靠性的内部机制; 因此, 当移植到数据报传输上时 TLS 实现会失效。DTLS 的目的仅对 TLS 做修正该问题所必需的最小改动。在最大可行范围内, DTLS 与 TLS 相同。每当需要发明新机制时, 我们尽量以保持 TLS 风格的方式进行。
不可靠性在两个层面上给 TLS 造成问题:
-
TLS 不允许独立解密各条记录。因为完整性校验依赖于序列号, 若记录 N 未被接收, 则记录 N+1 的完整性校验将基于错误的序列号因而失败。(注意在 TLS 1.1 之前没有显式 IV, 因此解密也会失败。)
-
TLS 握手层假定握手消息被可靠交付, 若这些消息丢失则会失效。
本节其余部分描述 DTLS 用于解决这些问题的方法。
3.1. Loss-Insensitive Messaging (与丢包无关的消息处理)
在 TLS 的流量加密层 (称为 TLS 记录层 (TLS Record Layer)) 中, 记录并非相互独立。存在两类记录间依赖:
-
密码学上下文 (流密码密钥流 (stream cipher key stream)) 在记录之间保留。
-
反重放 (anti-replay) 与消息重排保护由包含序列号的 MAC 提供, 但序列号在记录中是隐式的。
DTLS 通过禁止流密码 (stream ciphers) 解决第一个问题。DTLS 通过添加显式序列号 (explicit sequence numbers) 解决第二个问题。
3.2. Providing Reliability for Handshake (为握手提供可靠性)
TLS 握手是步进式密码握手。消息必须按既定顺序发送与接收; 任何其他顺序均为错误。显然, 这与重排和消息丢失不兼容。此外, TLS 握手消息可能大于任意给定数据报, 从而产生 IP 分片问题。DTLS 必须为这两类问题提供修复手段。
3.2.1. Packet Loss (分组丢失)
DTLS 使用简单的重传定时器处理分组丢失。下图用 DTLS 握手的第一阶段演示基本概念:
Client Server
------ ------
ClientHello ------>
X<-- HelloVerifyRequest
(lost)
[Timer Expires]
ClientHello ------>
(retransmit)
客户端一旦发送 ClientHello 消息, 就期望看到来自服务器的 HelloVerifyRequest。然而, 若服务器消息丢失, 客户端知道 ClientHello 或 HelloVerifyRequest 之一已丢失并会重传。服务器收到重传时知道需要重传。
服务器也维护重传定时器, 并在定时器到期时重传。
注意超时与重传不适用于 HelloVerifyRequest, 因为这将要求在服务器上创建状态。HelloVerifyRequest 设计得足够小以免自身被分片, 从而避免交错多个 HelloVerifyRequest 的问题。
3.2.2. Reordering (重排)
在 DTLS 中, 每条握手消息在该握手中被赋予特定序列号。对等端收到握手消息时可迅速判断该消息是否为下一条期望消息。若是, 则处理; 若否, 则将其排队待先前所有消息收到后再处理。
3.2.3. Message Size (消息大小)
TLS 与 DTLS 握手消息可能相当大 (理论上可达 2^24-1 字节, 实践中为许多千字节)。相比之下, 若不希望 IP 分片, UDP 数据报通常限制在 1500 字节以下。为弥补该限制, 每条 DTLS 握手消息可分片到若干 DTLS 记录上, 每条记录拟放入单个 IP 数据报。每条 DTLS 握手消息同时包含分片偏移 (fragment offset) 与分片长度 (fragment length)。因此, 握有握手消息全部字节的接收方可以重组原始未分片消息。
3.3. Replay Detection (重放检测)
DTLS 可选择支持记录重放检测。所用技术与 IPsec AH/ESP 相同, 即维护已收记录的位图窗口 (bitmap window)。过旧而无法落入窗口的记录以及先前已收记录被静默丢弃。重放检测功能是可选的, 因为分组复制并不总是恶意的, 也可能由路由错误引起。应用可以设想检测重复分组并相应调整其数据传输策略。