摘要 :DTLS(Datagram Transport Layer Security)是专为 UDP 设计的加密通信协议,在保留 UDP 低延迟、无连接优势的同时,提供与 TLS 同等的机密性、完整性与身份认证。它通过记录层显式序列号与滑动窗口实现防重放,以握手消息超时重传与分片解决 UDP 不可靠问题,并借助 HelloVerifyRequest + 无状态 Cookie 抵御 DoS 攻击。本文梳理 DTLS 的设计思路、握手流程(以 DTLS 1.2 为例)及典型应用场景,并给出选型建议。
专为数据报协议( UDP)设计的加密通信协议,它在尽可能复用 TLS 逻辑的同时,解决了 UDP 不可靠、无连接带来的挑战。
1. DTLS (Datagram Transport Layer Security)
UDP 本身不保证可靠传输、不维护连接状态、不保证报文顺序。而传统 TLS 依赖 TCP 提供的这些特性。如果强行在 UDP 上跑 TLS,可能出现:
- 握手消息丢失 → 连接无法建立
- 报文乱序 → 解密失败
- 无连接状态 → 无法防御重放攻击
DTLS 的目标就是:在保留 UDP 低延迟、无连接优势的前提下,提供与 TLS 同等的安全保障(机密性、完整性、身份认证)。
1.1 DTLS 与 TLS 的核心差异
| 维度 | TLS(基于 TCP) | DTLS(基于 UDP) |
|---|---|---|
| 传输层 | TCP,可靠有序 | UDP,不可靠、可能乱序 |
| 记录边界 | 字节流,无边界 | 每个数据报独立成记录 |
| 握手可靠性 | 依赖 TCP 重传 | 自带超时重传与分片 |
| 防重放 | 依赖 TCP 序列号 | 记录层显式序列号 + 滑动窗口 |
| 抗 DoS | 依赖 TCP 半连接队列 | HelloVerifyRequest + Cookie |
1.2 为什么不能直接复用 TLS
TLS 的握手协议假设底层是可靠、有序的字节流。一旦换成 UDP:
- 握手消息可能丢失,导致双方永远等不到对方的下一步;
- 消息乱序到达,接收方无法判断当前处于握手的哪个阶段;
- 没有连接状态,攻击者可以伪造源地址发起大量握手请求,耗尽服务器资源。
因此 DTLS 必须在 TLS 的基础上,额外解决可靠性 、有序性 和无连接状态这三个问题,这正是第 2 节设计思路要展开的内容。
2. DTLS 设计思路
2.1 报文边界与记录层
- TLS 将应用数据视为字节流,DTLS 则严格保持每个 UDP 数据报的边界。
- 每个 DTLS 记录(Record)包含
- 显式序列号(用于防重放和排序)
- 内容类型、版本、长度、数据载荷
- 接收方可以独立处理每个记录,单个包损坏不影响其他包
为什么需要显式序列号? 因为 UDP 不保证顺序,接收方必须依靠记录自带的序列号来判断是否乱序、是否重复,而不是依赖底层传输层。
2.2 握手消息的重传与状态机
- DTLS 握手协议引入了超时重传机制,但仅针对握手阶段
- 每个握手消息都携带消息序列号,接收方可以检测丢失和乱序。
- 握手消息支持分片(Fragment):当单个握手消息超过 UDP 的 MTU 时,可以分片发送,接收方重组。
重传策略:发送方为每个握手消息启动一个定时器,超时未收到确认就重传,并采用指数退避(每次超时时间翻倍),避免网络拥塞时加剧丢包。
2.3 . 防拒绝服务(DoS)攻击(HelloVerifyRequest)
这是 DTLS 独有 的机制。服务器收到 Client Hello 后,不立即分配资源,而是回复一个 HelloVerifyRequest,其中包含一个无状态 cookie。
客户端必须重发 ClientHello 并带上这个 cookie,服务器验证通过后才继续握手。
这有效防止了伪造源 IP 的放大攻击(类似 TCP SYN Flood)。
Cookie 为什么是"无状态"的? 服务器不保存每个客户端的会话,而是把客户端 IP、端口等信息用密钥做 HMAC 生成 cookie。客户端回传后,服务器重新计算比对即可验证,无需占用内存。
2.4 重放保护
记录层序列号用于检测重放包。接收方维护一个滑动窗口,丢弃重复或太旧的序列号。
滑动窗口原理:接收方记录已收到的最大序列号,并维护一个窗口(如 64 个包)。落在窗口左侧的序列号视为重放或过期包,直接丢弃;窗口内的重复包也丢弃。
注意:DTLS 不保证可靠传输,应用数据如果丢失,不会自动重传(除非应用层自己实现)。
3. DTLS 握手流程(以 DTLS 1.2 为例)
Client Server
| |
| -------- ClientHello (seq=0) ----------------> | (无状态,不分配资源)
| |
| <------- HelloVerifyRequest (cookie) ---------- |
| |
| -------- ClientHello (with cookie) ----------> | (验证cookie,开始握手)
| |
| <------- ServerHello (seq=0) ----------------- |
| <------- Certificate (seq=1) ----------------- |
| <------- ServerKeyExchange (seq=2) ----------- |
| <------- CertificateRequest (seq=3) ---------- | (可选)
| <------- ServerHelloDone (seq=4) ------------- |
| |
| -------- Certificate (seq=1) ----------------> |
| -------- ClientKeyExchange (seq=2) -----------> |
| -------- CertificateVerify (seq=3) -----------> | (可选)
| -------- ChangeCipherSpec (seq=4) ------------> |
| -------- Finished (seq=5) -------------------> |
| |
| <------- ChangeCipherSpec (seq=5) ------------- |
| <------- Finished (seq=6) -------------------- |
| |
| ========== 加密应用数据 ====================== |
- 序列号:每个握手消息都有递增的序列号,用于匹配请求和响应。
- 重传:如果客户端在超时时间内未收到 ServerHelloDone,会重传 ClientHello(带 cookie)。
- 分片:如果 Certificate 消息过大,会被分成多个片段,每个片段有分片偏移和总长度。
3.1 握手阶段拆解
第一阶段:抗 DoS 校验(2 次往返)
客户端先发送不带 cookie 的 ClientHello,服务器回复 HelloVerifyRequest 下发 cookie,客户端携带 cookie 重发 ClientHello。这一步在真正分配资源前完成身份校验,防止伪造源 IP 的握手风暴。
第二阶段:服务器认证与密钥协商(1 次往返)
服务器依次发送 ServerHello、Certificate、ServerKeyExchange、ServerHelloDone。客户端据此验证服务器身份,并计算出预主密钥(Pre-Master Secret)。
第三阶段:客户端认证与密钥确认(1 次往返)
客户端发送自己的 Certificate(可选)、ClientKeyExchange、CertificateVerify(可选),随后发送 ChangeCipherSpec 和 Finished,通知服务器后续消息将加密。服务器同样回复 ChangeCipherSpec 和 Finished,双方确认密钥一致后进入加密通信阶段。
3.2 与 TLS 1.2 握手的对比
| 阶段 | TLS 1.2 | DTLS 1.2 |
|---|---|---|
| 往返次数 | 2 次(TCP 已建立连接) | 3 次(多一次 cookie 校验) |
| 握手消息可靠性 | 依赖 TCP 重传 | 自带超时重传 |
| 大消息处理 | TCP 自动分段 | 应用层分片 + 重组 |
| 防重放 | TCP 序列号 | 记录层显式序列号 |
4. 典型应用场景
- WebRTC:浏览器间的实时音视频通信,使用 DTLS-SRTP 加密媒体流。
- IoT 协议:CoAP over DTLS,为受限设备提供安全通信。
- VPN:OpenVPN 的 UDP 模式默认使用 DTLS 或自定义加密层。
- 在线游戏:部分游戏使用 DTLS 保护对战数据,兼顾低延迟和安全性。
- SIP/VoIP:加密信令和媒体流,防止窃听。
4.1 各场景选型要点
| 场景 | 协议组合 | 关键诉求 |
|---|---|---|
| WebRTC | DTLS-SRTP | 低延迟 + 媒体流加密 |
| IoT | CoAP over DTLS | 轻量 + 受限设备兼容 |
| VPN | OpenVPN over UDP | 隧道加密 + 抗丢包 |
| 在线游戏 | DTLS | 低延迟 + 防作弊 |
| VoIP | DTLS-SRTP | 信令与媒体加密 |
4.2 选型建议
- 追求极致低延迟:优先 UDP + DTLS,但需在应用层处理丢包重传。
- 设备资源受限:CoAP over DTLS 比 HTTPS 更轻量,适合内存和 CPU 有限的 IoT 设备。
- 需要可靠传输:如果业务不能容忍丢包,建议仍用 TCP + TLS,或自行在 DTLS 之上实现可靠层。
5. 总结
DTLS 在保留 UDP 低延迟、无连接优势的同时,通过记录层显式序列号、握手消息超时重传与分片、HelloVerifyRequest 抗 DoS、滑动窗口防重放等机制,提供了与 TLS 同等级别的安全保障。
核心要点回顾:
- DTLS 严格保持 UDP 数据报边界,每个记录独立处理;
- 握手阶段自带重传与分片,不依赖 TCP 的可靠性;
- HelloVerifyRequest + 无状态 Cookie 是 DTLS 独有的抗 DoS 手段;
- 记录层序列号 + 滑动窗口实现防重放;
- 应用数据不保证可靠传输,丢包需应用层自行处理。
适用场景:WebRTC、CoAP over DTLS、OpenVPN、在线游戏、VoIP 等对延迟敏感、又需要加密保护的场景。
延伸阅读 :DTLS 1.3(RFC 9147)进一步减少了握手往返次数,并移除了对 TLS 1.2 的兼容负担,适合对握手延迟有更高要求的场景。
其他类似技术: QUIC 是 Google 提出、后来被 IETF 标准化为 HTTP/3 底层传输的协议 直接运行在 UDP 之上,并将传输层(类似 TCP 的功能)和 TLS 1.3 深度整合在一起。