跳到主要内容

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 造成问题:

  1. TLS 不允许独立解密各条记录.因为完整性校验依赖于序列号, 若记录 N 未被接收, 则记录 N+1 的完整性校验将基于错误的序列号因而失败.(注意在 TLS 1.1 之前没有显式 IV, 因此解密也会失败.)

  2. TLS 握手层假定握手消息被可靠交付, 若这些消息丢失则会失效.

本节其余部分描述 DTLS 用于解决这些问题的方法.

3.1. Loss-Insensitive Messaging (与丢包无关的消息处理)​

在 TLS 的流量加密层 (称为 TLS 记录层 (TLS Record Layer)) 中, 记录并非相互独立.存在两类记录间依赖:

  1. 密码学上下文 (流密码密钥流 (stream cipher key stream)) 在记录之间保留.

  2. 反重放 (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).过旧而无法落入窗口的记录以及先前已收记录被静默丢弃.重放检测功能是可选的, 因为分组复制并不总是恶意的, 也可能由路由错误引起.应用可以设想检测重复分组并相应调整其数据传输策略.