DTLS 数据报传输层安全协议:UDP 环境下的安全通信原理与实现

协议详解 · 2026-06-26

概述

传输层安全协议(TLS)是互联网安全通信的基石。标准 TLS 建立在 TCP 之上,依赖 TCP 提供的可靠传输特性:数据按序到达、自动重传、流量控制与拥塞控制。然而,在 UDP 环境下,这些特性不复存在:数据包可能丢失、乱序到达、或重复发送。

数据报传输层安全协议(Datagram Transport Layer Security, DTLS)正是为解决这一问题而设计的协议。DTLS 保持了 TLS 的安全语义,同时在不可靠传输之上建立了安全通道。理解 DTLS,不仅是理解 WebRTC、OpenVPN、TLS over QUIC 等现代系统的安全基础,也是评估物联网(IoT)和实时通信安全性的关键。

DTLS 的核心设计挑战在于:在不假定可靠传输的前提下,实现与 TLS 同等级别的机密性、完整性和身份认证,同时应对 DTLS 特有的数据包丢失和放大攻击风险。本文将从 DTLS 1.2(RFC 6347)和 DTLS 1.3(RFC 9147)两个版本出发,深入剖析协议设计与工程实践。

DTLS 的设计原则

DTLS 的设计哲学是「对 TLS 改动最小化」。它复用 TLS 的握手协议和密码套件定义,在此基础上仅增加最小化的机制以适应 UDP 传输。

与 TLS 的核心区别

DTLS 相对于 TLS 进行了以下结构性调整:

特性TLS (TCP)DTLS (UDP)
传输层有序、可靠不可靠、无顺序保证
握手消息通过 TCP 流隐式排序显式序列号排序
数据完整性TCP 保证丢失包会被重传需 DTLS 自行处理丢失和重传
防 DoS 攻击SYN Cookie(TCP 层)DTLS Cookie(协议层)
记录格式Length + PayloadEpoch + Sequence Number + Length + Payload
握手消息不限制大小必须支持分段和重组
关键设计原则:
  • 序列号可见化:TLS 中序号隐含在 TCP 字节流中;DTLS 需要在每条记录中显式携带序列号,用于消息排序和重放检测。
  • 握手消息分段:TLS 握手消息可能超过 TCP 段大小;UDP 通常受 MTU 限制(通常 1500 字节,扣除 IP/UDP 头部后约 ~1400 字节),DTLS 握手消息必须支持显式分段和重组。
  • 状态机重传:DTLS 需要建立状态机来跟踪发送的消息并在超时后重传。
  • DoS 防护:UDP 无连接特性使得源 IP 欺骗更容易,DTLS 采用 Cookie 握手机制防止无状态资源消耗。

DTLS 1.2 协议详解(RFC 6347,2012)

DTLS 1.2 在 TLS 1.2 的基础上添加了上述机制,是当前部署最广泛的版本。

记录协议

DTLS 记录协议在 TLS 记录协议的基础上,在记录头部插入了两个新字段:

CODE
0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    类型     |   版本      |        Epoch       |   序列号(16 位)  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    序列号(续,16 位)                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         长度          |                                       |
+-+-+-+-+-+-+-+-+-+-+-+-+                                       |
|                            密文载荷                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

字段含义:

  • 类型(Type):20(ChangeCipherSpec)、21(Alert)、22(Handshake)、23(Application Data)
  • 版本(Version):DTLS 1.2 对应 {254, 253}(回退表示法,避免与 TLS 混淆)
  • Epoch(时代):每次密钥更新(KeyUpdate)或握手完成后递增,用于隔离不同密钥的代
  • 序列号(Sequence Number):64 位,由 Epoch(高 16 位)和 Record Sequence Number(低 48 位)组成,用于重放检测和消息排序
  • 长度(Length):载荷长度(不包含头部)
记录层加密使用序列号作为 nonce 的一部分,防止同一Epoch内数据包重放。

握手机制(Handshake Protocol)

DTLS 1.2 的握手流程在 TLS 1.2 的基础上增加了两个关键阶段:

与 TLS 1.2 的三个关键差异:

#### 1. HelloVerifyRequest 防 DoS 攻击

TLS 1.2 握手中,服务器在收到 ClientHello 后就开始分配状态(随机数、Diffie-Managed 参数等)。在 UDP 源 IP 可伪造的环境下,攻击者可以发起海量 ClientHello 请求,迫使服务器不断分配内存和计算资源。

DTLS 的解决方案是:无状态 Cookie 交换

  • 客户端发送 ClientHello(无 Cookie)
  • 服务器不立即分配状态,而是生成一个 Stateless Cookie(包含客户端 IP、端口和时间的 HMAC 签名),通过 HelloVerifyRequest 发回
  • 客户端重新发送 ClientHello,携带此前收到的 Cookie
  • 服务器验证 Cookie 有效性后,才真正开始握手流程
对于已分配资源的合法客户端,重传开销极小;而伪造源 IP 的攻击者无法收到 Cookie 验证消息,因此无法完成握手的第二步。

#### 2. 握手消息的分段

UDP 要求单个数据报尽量不超过 MTU(通常 1400 字节,保守值 - DTLS 规范建议初始使用 1024 字节)。TLS 握手消息(如 CertificateServer 证书链)可能远超此限制。

DTLS 握手消息引入了分段字段:

CODE
0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  握手类型     |    消息长度(24 位)                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           分片偏移(24 位)     |     分片长度              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            分片载荷                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • 消息长度:整个握手消息的完整长度(含所有分片的数据)
  • 分片偏移:当前分片在完整消息中的零起偏移量
  • 分片长度:当前分片的长度
服务器收到分片后暂存并重组,全部收集完毕后按普通握手逻辑处理。

#### 3. 重传定时器

与 TLS 依赖 TCP 自动重传不同,DTLS 必须在超时后主动重传。DTLS 定义了指数退避重传策略:

  • 初始重传超时:1 秒(RFC 6347 建议值)
  • 每次超时后,将超时时间翻倍
  • 当达到最大重传超时(默认 60 秒)后,持续使用最大值
  • 收到对端消息后,重置定时器到初始状态
重传停止的条件是收到预期类型的下一个握手消息,或达到最大重试次数后放弃握手。

密钥调度

DTLS 复用 TLS 1.2 的密钥调度:

  • Premaster Secret → Master Secret → Key Block
  • Key Block 派生:Client Write MAC Key、Server Write MAC Key、Client Write IV、Server Write IV
DTLS 的特别之处:在握手过程中(Before Finished 消息)不发送应用数据;仅在所有握手消息交换完毕并验证 Finished 消息后才开放应用数据通道。

ChangeCipherSpec 协议

DTLS 保留 TLS 的 ChangeCipherSpec 协议(独立消息类型 20),但需要注意:

  • 在 DTLS 中,ChangeCipherSpec 的发送和接收不受握手消息分段的限制
  • Future Epoch(下一个加密代)的密钥消息必须在当前条记录层安全队列中进行原子交换

DTLS 1.3 协议详解(RFC 9147,2022)

DTLS 1.3 基于 TLS 1.3 协议构建,借鉴了 TLS 1.3 的简化设计哲学,同时保留了 DTLS 特有的 UDP 适配机制。

主要改进

#### 1. 更紧凑的握手与重试机制

DTLS 1.2 的 HelloVerifyRequest 是一个独立的协议消息。DTLS 1.3 将其整合到 ServerHello 消息中:

HelloRetryRequest 本质上是 TLS 1.3 的 HelloRetryRequest 扩展,内嵌了 Cookie extension。这减少了了一次消息往返,也简化了状态机设计。

#### 2. 序列号与 Epoch 设计

DTLS 1.3 不再区分握手阶段(handshake epoch)和应用数据阶段(application epoch)。每条记录都携带独立的 64 位序列号。加密 nonce 由序列号与固定的 IV 写入密钥(write_iv)异或生成(类似 TLS 1.3 的方式)。

序列号规则:

  • 对每个写入密钥(写保护):从 0 开始逐记录递增
  • 达到序列号最大值后,必须触发密钥更新(KeyUpdate)
  • 序列号低于预期值的数据包被丢弃(提供隐式重放保护)
#### 3. 防降级攻击

DTLS 1.3 握手完成后,双方保护性地计算 verify_data 并包含在 Finished 消息中。verify_data 包含完整的 ClientHello(含 extensions 如 supported_versions),防止了中间人篡改协商的协议版本。

#### 4. 0-RTT 数据

DTLS 1.3 支持 0-RTT(Zero Round Trip Time)数据发送:

  • 客户端在首次握手后,从 Early Data extension 获得 PSK(预共享密钥)
  • 下次连接时,客户端在 ClientHello 中将 PSK 和 0-RTT 数据一起发送
  • 服务器选择接受或拒绝 0-RTT 数据,回退到 1-RTT 握手
安全注意事项:0-RTT 数据不具前向安全性(PSK 泄露可解密)且可被重放(同一 PSK 在nonce 空间内可能被投毒),因此通常用于幂等 GET 请求或非敏感读取操作。

DTLS 1.3 密钥调度

DTLS 1.3 的密钥调度完全遵循 TLS 1.3 的 TLS 1.3 Key Schedule:

与 TLS 1.3 不同之处在于:

  • 密钥派生完成后,需要计算 client_handshake_traffic_secretserver_handshake_traffic_secret 以保护加密的握手消息
  • 握手完成后使用 client_application_traffic_secretserver_application_traffic_secret 保护应用数据
  • 握手阶段的 Finished 消息使用握手阶段密钥加密,而非应用阶段密钥

DTLS 密钥派生细节

DTLS 1.3 的加密套件定义与 TLS 1.3 保持一致:

TLS 1.3 密码套件密钥交换认证加密哈希
TLS_AES_128_GCM_SHA256ECDSA/Ed25519ECDSA/Ed25519AES-128-GCMSHA-256
TLS_AES_256_GCM_SHA384ECDSA/Ed25519ECDSA/Ed25519AES-256-GCMSHA-384
TLS_CHACHA20_POLY1305_SHA256ECDSA/Ed25519ECDSA/Ed25519ChaCha20-Poly1305SHA-256
DTLS 在协商密码套件后,通过 TLS 1.3 的标准密钥派生流程生成密钥材料。加密 nonce(encryption nonce)由序列号与固定写 IV(write_iv)异或生成,确保非重复性。

DTLS 的应用场景

WebRTC

WebRTC(Web Real-Time Communication)是 DTLS 最广泛应用的场景。在 WebRTC 中:

  • 媒体流通过 DTLS-SRTP(SRTP Protection via DTLS)协议保护
  • DTLS 握手在 ICE(Interactive Connectivity Establishment)建立连接后进行
  • 握手成功后,DTLS 派生 SRTP 密钥材料,后续媒体数据使用 SRTP/SRTCP 传输
  • 支持 P2P 通信,无需服务器中转加密密钥
  • 广泛用于视频会议(如 Google Meet、Microsoft Teams、Zoom Peer-to-Peer)、语音通话和实时文件传输
关键流程:
  • ICE STUN 绑定请求建立 NAT 穿透后的 UDP 连接
  • DTLS 握手(同时发送 ClientHello 或通过 STUN 的 parallel check)
  • SRTP 密钥导出:DTLS-SRTP Key Derivation(RFC 5764)
  • 媒体流加密传输(AES-128-CM-HMAC-SHA1-80 或 AES-256-CM-HMAC-SHA1-80)

OpenVPN

OpenVPN 默认使用 UDP 模式。它利用 DTLS 建立隧道密钥:

  • 使用 --tls-auth--tls-crypt 选项提供额外的 HMAC 认证层
  • 数据信道(data channel)使用协商的对称密钥加密
  • 支持密钥重协商(renegotiation)以刷新会话密钥
  • 支持用户名/密码证书的多因素认证

QUIC / HTTP3

QUIC(RFC 9000)虽然不直接使用 DTLS,但复用了 TLS 1.3 握手协议:

  • QUIC 集成 TLS 1.3 用于加密握手
  • QUIC 使用 DTLS 类似的思路处理丢包和重序(自建可靠传输层)
  • HTTP/3 依赖 QUIC 提供 HTTPS 级别的安全保障

物联网与受限环境

DTLS 是物联网安全协议的核心组件:

  • DTLS-PSK(预共享密钥):适用于受限设备,无需证书握手,减少计算和带宽开销
  • CoAP over DTLS:RFC 7252 定义的应用层协议结合 DTLS,适用于低功耗有损网络(LLN)
  • OSCORE(Object Security for Constrained RESTful Environments):RFC 8613 提供应用层安全,绕过 DTLS 逐跳加密的中间节点信任问题
Ciphertext Record 格式开销:
  • DTLS 记录头相比 TLS 约增加 8 字节(epoch + sequence number + explicit IV)
  • 在 IPv6 / UDP 环境下,MTU 限制对短消息的影响需要考虑

安全分析与已知攻击

DoS 放大攻击(Amplification Attack)

攻击者伪造受害者的 IP 地址向 DTLS 服务器发送 ClientHello,服务器随后发送大得多的 ServerHello + Certificate + ServerKeyExchange 消息给受害者。由于证书消息通常远大于 ClientHello(放大因子可达 20-50 倍),攻击者可以以少量带宽消耗目标服务器的计算和网络资源。

防护措施:

  • HelloVerifyRequest(1.2)/ HelloRetryRequest(1.3)的 Cookie 机制:最直接的防护
  • 初始连接速率限制(Rate Limiting)
  • MTU 限制:初始 ClientHello ≤ MTU(约 1400 字节),Certificate 链长度受限

重放攻击

冒落者捕获并重放此前发送的 handshake 消息或 application data 消息。

DTLS 的防护机制:

  • 序列号检查:每条记录携带的序列号,接收方维护一个滑动窗口(类似 IPsec ESP 的 replay window),检测并丢弃重复序列号
  • Finished 消息验证:包含整个握手消息的 HMAC 验证,防止握手消息插入
  • Epoch 边界隔离:密钥更新后,新记录的 Epoch 加 1,防止跨 Epoch 重放

分片攻击

攻击者构造恶意分片以绕过检测:

  • 微小分片攻击:将握手消息分成极小的段,迫使目标分配大量内存存储不完整的分片
  • 重叠分片攻击:发送偏移量重叠的分片,目标重组行为因操作系统而异
防护措施:
  • 分片超时:收到一个分片后,设定超时(默认 60 秒),超时后丢弃所有部分分片
  • 分片内存限制:单个握手消息的所有分片占用内存上限
  • 重叠检测:同一偏移量只保留最新收到的分片

密码套件降级

攻击者篡改 ClientHello 中的 cipher_suites 列表,迫使双方使用较弱的密码套件。

DTLS 1.3 的 Finished 消息验证机制完全阻止了此类攻击。DTLS 1.2 依赖于 MAC 验证(包含在 CertificateVerify 和 Finished 消息中),但如果客户端不验证服务器的签名权限,中间人仍可能进行降级攻击。

最佳实践:

  • 服务器配置优先选择 AEAD 密码套件(如 AES-GCM、ChaCha20-Pylult)
  • 禁用 CBC 模式和 RC4 等已知脆弱的密码套件
  • 客户端和服务器的密码套件列表使用 ACL(访问控制列表)集中管理

DTLS 1.2 vs DTLS 1.3:设计演进

维度DTLS 1.2(RFC 6347)DTLS 1.3(RFC 9147)
基础 TLS 版本TLS 1.2TLS 1.3
握手消息分片显式 divide 字段类似,但更简化
防 DoS独立 HelloVerifyRequest集成到 HelloRetryRequest
最少往返数3 次(含 Cookie)2 次(1-RTT)
握手消息加密仅 Finished 后握手密钥加密服务端握手消息加密
重传策略指数退避,固定上限指数退避,PLPMTUD-aware
0-RTT 数据不支持支持(需 PSK resume)
序列号空间48 位(2 个 24 位段)64 位统一空间
密钥派生TLS 1.2 PRFTLS 1.3 HKDF-Expand-Label
安全握手可选签名 + 证书验证强制服务器认证(+ PSK 可选)
最大明文记录2^14 bytes2^14 bytes
DTLS 1.3 的核心优势在于减少了握手往返次数(包括整合了防止 DoS 的 Cookie 阶段),同时获得了 TLS 1.3 的安全特性(强制前向安全、更强的密钥分离、服务端握手消息加密)。

DTLS 工程实践建议

1. MTU 与分片策略

DTLS 手持设备或卫星链路场景下,MTU 可能远小于 1500 字节。建议:

  • 初始握手消息分片大小不超过 1024 字节(保守值,适应 IPv6 路径)
  • 支持 Path MTU Discovery(PMTUD)以避免 IP 层分片
  • Certificate 链尽可能使用较短的证书层级(Root CA → Server,而非 Root → Intermediate → Server)

2. 证书验证与指纹

在 WebRTC 场景中,DTLS 证书指纹(fingerprint)通过 SDP(Session Description Protocol)传递,用于 DTLS 握手时服务器身份验证:

CODE
a=fingerprint:sha-256 AB:CD:EF:...

这种模式绕过了传统的 PKI 信任链验证,适用于 P2P 通信场景。但需要确保 SDP 交换通道本身的安全(如通过 HTTPS 获取 SDP)。

3. 密钥更新(KeyUpdate)

DTLS 支持按需密钥更新(KeyUpdate 握手协议),通常在以下时机触发:

  • 加密数据量达到阈值(如 AES-GCM 的 2^64 字节上限前)
  • 序列号空间耗尽前
  • 定期刷新以限制密钥泄露的影响

4. 与 QUIC 的选择

对于新项目,评估安全传输协议时:

  • 需要 P2P 通信或已使用 UDP 选 → DTLS
  • 需要集成 HTTP 语义 → QUIC(TLS 1.3 over QUIC)
  • 需要兼容性(现有 UDP 基础设施) → DTLS 1.2 + 向前兼容

总结

DTLS 协议通过在 TLS 之上叠加序列号、重传、分段和 Cookie 等机制,成功将安全通信扩展到 UDP 传输环境。DTLS 1.2 提供了成熟稳定的安全通信基础,DTLS 1.3 则通过协议简化进一步提升了性能和安全性。

理解 DTLS,对于构建 WebRTC 实时通信、OpenVPN 安全隧道、以及受限环境下的物联网安全通信都具有核心价值。随着 5G 和物联网的发展,DTLS 作为 UDP 安全传输标准的地位将更加稳固。

参考来源

相关实践

[^1]: Eronen, P., Ed., "Advanced Encryption Standard (AES) Key Wrap Algorithm", RFC 3394, September 2002. [^2]: Housley, R., "Cryptographic Message Syntax (CMS)", RFC 5652, September 2009. [^3]: [^4]: [^5]: