网络协议:DTLS 1.2

DTLS 概述

DTLS = Datagram Transport Layer Security

对于 TLS,相信大家都比较熟悉, 而 DTLS 的却不常见,这篇文章我们就来了解一下 DTLS 协议。

对于基于 TCP 的协议

如果传输的数据有安全性要求,那么协议往往只需要简单的定义一下如何和 TLS 协议交互, 便能确保安全的传输数据。而通常这里的交互都非常简单,最简单的交互就是直接要求 TCP 链接建立之后,便开始协商 TLS 参数,接着所有的数据便可以直接通过 tls 加密上层协议的数据进行传输即可。

例如, HTTP 协议。 如果需要安全的传输 HTTP 协议,便需要使用 HTTPS 协议。 而 HTTPS 协议也只是要求建立 TCP 链接之后,开始 TLS 握手,握手成功之后,使用 TLS 协商出来的加密参数,对明文的 HTTP 协议数据包进行加密,然后再网络上传输,便完成了把 HTTP 变成 HTTPS。

对于基于 UDP 的协议:

由于 UDP 协议无法直接使用 TLS 协议,通常如果协议需要安全的传输数据,便需要在协议设计的初期便将数据安全考虑进来。 比如 Kerberos 协议,它就自己定义了一套数据加解密的协议。

但是这里就有弊端,就是每个协议都需要自己设计安全加密,而安全加密却是一门复杂的学问,一不小心,便可能设计一个并不安全的协议。

为此,DTLS 就是给 UDP 使用的 TLS 协议。

概述

DTLS 用于给基于 UDP 的协议提供安全的传输数据的功能。

如果你在使用一个 UDP 协议,但是这个协议自身没有提供安全的传输数据的功能,那么你可以考虑使用 DTLS。

DTLS 是 TLS 的衍生协议。 为了能和 UDP 一起工作,将 TLS 协议做了必要的修改。
最主要的就是: DTLS 不要求底层传输协议是 可靠的有序的

面对的主要问题

将 TLS 直接应用于 UDP 上面临的主要问题是:UDP 数据传输会丢包,数据包会乱序
而 TLS 的设计要求底层传输协议是可靠的,因此不能直接将 TLS 用于 UDP 协议上。

DTLS 想要对 TLS 做最小的改动,然后让 TLS 可以和 UDP 一起工作。

TLS 和 UDP 主要不兼容的部分有两个:

  1. 每个 record 的加解密不是独立的(independenty)。
    因为 TLS 的完整性检测(integrity check) 依赖于隐式的 sequence number。 也就是说,如果我想要正确的检测 record N 的完整性,我需要收到所有 record N 之前的 record, 否则 record N 的完整性将无法正确检测。

  2. TLS 握手层总是假定握手数据包是可靠传输的(有序,且不会丢包)。 对于 UDP,如果丢包或者乱序发生,那么 TLS 握手也会失败。

那么 DLTS 如何解决这些问题的?

丢包不敏感设计

TLS record 之间不独立,record 之间的主要关联为:

  1. 加解密上下文(Cryptographic context). 这里针对流式加密算法(stream cipher key stream).
  2. TLS 依赖隐式的 sequence number 来做反重放攻击(anti-replay) 和 MAC 校验。但是 UDP 不能保证有序,因此这里会出问题。

对于问题 1, DTLS 通过 禁用流式加密算法 解决。
对于问题2, DTLS 通过 添加显示的 sequence number 解决。

握手包的可靠传输设计

TL S握手的流程是有特定的流程的,要求发送什么包,然后接受什么包,必须按照预设的顺序进行。乱序会被认为是一个握手错误。 这很明显和 UDP 不兼容。

另外一个问题是,UPD 有最大包的限制,这里也需要特殊处理。

1. 丢包问题

毫无疑问,丢包就得重传咯。DTLS 使用一个简单的超时重传机制

例如,我们作为客户端发送了 ClientHello,然后等待服务器响应 HelloVerifyRequest。 但是 Hello Verify Request 包丢了。
在这里插入图片描述
客户端在等待服务器响应 HelloVerifyRequest,知道本地记录的超时时间还没收到,它便认为发生了丢包,因此需要重传 ClientHello。

2. 乱序问题

在 DTLS 中,每个握手消息都有一个唯一的 sequence number。对方可以通过查看收到的握手消息中的 sequence number 来判断消息是否发生了乱序。

如果发生了乱序,可以选择缓存提前到达的消息或者丢弃它等待对方重传。

3. 重放检测

这个特定是可选的,不强制要求实现。 这里使用的技术来自 IPsec AH/ESP。

DTLS 和 TLS 的不同

前面我们也说了,DTLS 是TLS 的衍生品,这里我们来看看都有哪些不同处:

Record layer

这里相比于 TLS, record 数据包中多加了两个字段: epochsequence_number.

在这里插入图片描述
epoch:
一个计数器。
这个计数器在每次 cipher 状态变化的时候需要递增。初始时为 0。

sequence_number:
每个 record 都需要设置一个 sequence number. 从 0 递增。
对于每个 epoch, sequence number 是独立的。
重传时, sequence_number 依然需要递增。

Record 数据加密

  1. Null cipher: 和 TLS 1.2 相同。
  2. Standard Stream Cipher: TLS 1.2 中只定义了 RC4 这个一个。 但是它不能再 DTLS 中使用。
  3. Block Cipher: 和 TLS 1.2 相同。
  4. AEAD Ciphers: 和 TLS 1.2 相同。

非法的 Record

在 TLS 中,非法的握手消息会导致握手流程失败。 但是在 DTLS 中,非法的握手消息应该被丢弃, 不要报错。
如果特定实现决定在这种情况下回复 Alert, 那么这个 Alert 是一个 fatal level alert.

Handshake Protocol

1. 如何应对拒绝服务攻击

DTLS 为此引入了 HelloVerifyRequest 握手包。

流程如下:

在这里插入图片描述

  1. 握手开始,客户端发送 ClientHello 到服务器
  2. 服务器收到 ClientHello 之后先不回复 ServerHello。而是回复一个 HelloVerifyRequet。 这个包中携带一个 Cookie
  3. 客户端收到 HelloVerifyRequet, 将其中的 Cookie 附带到新的ClientHello 中再次发送到服务器。

因此,对 TLS 的 Client Hello 消息做了修改。新加了 Cookie 字段。
在这里插入图片描述
新的结构 HelloVerifyRequest 的结果如下:
在这里插入图片描述

2. 新的 Handshake 消息结构

为了处理 UDP 的丢包,乱序,重传,还有分帧, DTLS 对握手消息的结构做了如下调整:
在这里插入图片描述
message_seq:

  • 第一个握手消息的 message_seq 是 0, 握手流程中的其他消息中的 message_seq 以此增加。
  • 重传的时候, message_seq 保持不变。 注意,这里和 record 中的 sequence number 不同,重传时, sequence number 是需要重新赋值的。
  • DTLS 实现可以通过这个字段来判断是否发生了乱序,重传等。

例子:
在这里插入图片描述

3. 分帧

当某个消息的内容超过最大 UDP 包大小,需要将该消息分帧放入多个UDP 包中发送。

Handshake.fragment_offsetHandshake.fragment_length 用于分帧。

3. 重传

采用超时重传机制。没有规定必须如何实现,协议实现者可以自行设计。


DTLS 的协议我们就介绍完毕了,谢谢!

  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VFSSoft

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值