Java实现DTLS之技术背景&原理(一)


前言

需求:升级服务侧SDK,实现与灯控器之间DTLS加密通信,代替SM4国密。目前通信是采用UDP协议并实现SM4国密加密,为了提升产品竞争力需要实现DTLS,因此深挖学习了下DTLS技术背景、原理等。


一、DTLS是什么?

DTLS代表“Datagram Transport Layer Security”(数据报传输层安全),它是一种基于传输层协议的安全通信协议。DTLS的设计目标是为UDP(User Datagram Protocol)提供加密和认证功能,以保证数据在不可靠的网络环境中的安全传输。

与传统的TLS(Transport Layer Security)协议相比,DTLS更适用于无连接的通信方式,如UDP。UDP是一种无连接的传输协议,相较于TCP,它更快速且具有较低的延迟,但缺乏可靠性和安全性。使用DTLS可以在UDP通信中提供与TLS相似的安全特性,如加密、数据完整性验证和身份认证。

DTLS使用了与TLS类似的协议流程和加密算法,包括握手协议、记录协议和密钥交换等。它通过使用数据报(Datagram)的封装,将TLS协议适配到UDP上,从而克服了UDP不可靠性和无连接性的问题。

DTLS的一些主要特性包括:

  1. 加密:DTLS使用对称加密和非对称加密算法,如AES、RSA和Diffie-Hellman,以保护传输的数据的机密性。
  2. 完整性保护:使用MAC(Message Authentication Code)来验证数据的完整性,可以检测数据被篡改的情况。
  3. 报文重组:在传输过程中,DTLS具备报文重组的能力,以处理因网络抖动或乱序导致的数据包乱序问题。

DTLS被广泛应用于各种需要在不可靠的网络环境中进行安全通信的应用,如VoIP(Voice over IP)、视频流传输、物联网设备通信等。通过添加安全层,DTLS提供了对这些应用的保护和安全性,同时保留了UDP的高效性和低延迟的优势。

二、RFC6347标准定义DTLS

1.中文翻译

以下是DTLS v1.2中文翻译的原文,避免博主不在继续维护因此复制到此处。

Internet Engineering Task Force (IETF) E. Rescorla
Request for Comments: 6347 RTFM, Inc.
Obsoletes: 4347 N. Modadugu
Category: Standards Track Google, Inc.
ISSN: 2070-1721 January 2012
数据报传输层安全版本1.2
摘要
本文件规定了数据报传输层安全(DTLS)协议的1.2版。DTLS协议为数据报协议提供通信隐私。该协议允许客户机/服务器应用程序以防止窃听、篡改或消息伪造的方式进行通信。DTLS协议基于传输层安全(TLS)协议,并提供等效的安全保证。DTLS协议保留了底层传输的数据报语义。本文档更新了DTLS 1.0以与TLS 1.2版配合使用。
关于下段备忘
这是一份互联网标准跟踪文件。
本文件是互联网工程任务组(IETF)的产品。它代表了IETF社区的共识。它已经接受了公众审查,并已被互联网工程指导小组(IESG)批准出版。有关互联网标准的更多信息,请参见RFC 5741第2节。
有关本文件当前状态、任何勘误表以及如何提供反馈的信息,请访问http://www.rfc-editor.org/info/rfc6347.
版权公告
版权所有(c)2012 IETF信托基金和确定为文件作者的人员。版权所有。
本文件受BCP 78和IETF信托有关IETF文件的法律规定的约束(http://trustee.ietf.org/license-info)自本文件出版之日起生效。请仔细阅读这些文件,因为它们描述了您对本文件的权利和限制。从本文件中提取的代码组件必须包括信托法律条款第4.e节中所述的简化BSD许可证文本,并提供简化BSD许可证中所述的无担保。
本文件可能包含2008年11月10日之前发布或公开的IETF文件或IETF贡献中的材料。控制某些材料版权的人员可能未授予IETF信托允许在IETF标准流程之外修改此类材料的权利。在未从控制此类材料版权的人员处获得充分许可的情况下,不得在IETF标准流程之外修改本文件,也不得在IETF标准流程之外创建其衍生作品,除了将其格式化以RFC形式发布或将其翻译成英语以外的其他语言。
在这里插入图片描述
1.介绍
TLS[TLS]是用于保护网络流量的最广泛部署的协议。它广泛用于保护Web流量和电子邮件协议,如IMAP[IMAP]和POP[POP]。TLS的主要优点是它提供了一个透明的面向连接的通道。因此,通过在应用层和传输层之间插入TLS,很容易保护应用协议。但是,TLS必须运行在可靠的传输通道上——通常是TCP[TCP]。因此,它不能用于保护不可靠的数据报流量。
越来越多的应用层协议被设计为使用UDP传输。特别地,诸如会话发起协议(SIP)[SIP]和电子游戏协议之类的协议越来越流行。(请注意,SIP可以在TCP和UDP上运行,但在某些情况下UDP更可取。)目前,这些应用程序的设计者面临着许多不令人满意的选择。首先,他们可以使用IPsec[RFC4301]。然而,由于[WHYIPSEC]中详述的许多原因,这仅适用于某些应用。其次,他们可以设计定制的应用层安全协议。不幸的是,尽管应用层安全协议通常提供优越的安全属性(例如,S/MIME情况下的端到端安全性),但它们通常需要大量的设计工作——而在TLS上运行协议所需的工作相对较少。
越来越多的应用层协议被设计为使用UDP传输。特别地,诸如会话发起协议(SIP)[SIP]和电子游戏协议之类的协议越来越流行。(请注意,SIP可以在TCP和UDP上运行,但在某些情况下UDP更可取。)目前,这些应用程序的设计者面临着许多不令人满意的选择。首先,他们可以使用IPsec[RFC4301]。然而,由于[WHYIPSEC]中详述的许多原因,这仅适用于某些应用。其次,他们可以设计定制的应用层安全协议。不幸的是,尽管应用层安全协议通常提供优越的安全属性(例如,S/MIME情况下的端到端安全性),但它们通常需要大量的设计工作——而在TLS上运行协议所需的工作相对较少。
DTLS 1.0[DTLS1]最初定义为[TLS11]中的增量。本文档介绍了DTLS的新版本DTLS 1.2,定义为TLS 1.2[TLS12]的一系列增量。没有DTLS 1.1;为了使版本号与TLS一致,跳过了该版本号。此版本还澄清了DTLS 1.0规范中的一些混淆点。
同时使用DTLS 1.2和DTLS 1.0的实现可以与只使用DTLS 1.0的实现进行互操作(当然使用DTLS 1.0),正如TLS 1.2实现可以与TLS的早期版本进行互操作(有关详细信息,请参见[TLS12]的附录E.1),但没有SSLv2或SSLv3的DTLS版本,因此,这些协议的向后兼容性问题不适用。

1.1. 需求术语
本文件中的关键词“必须”、“不得”、“要求”、“应”、“不应”、“应”、“不应”、“建议”、“可”和“可选”应按照RFC 2119[REQ]中的说明进行解释。
2. 使用模型
DTLS协议旨在保护通信应用程序之间的数据安全。它被设计为在应用程序空间中运行,不需要任何内核修改。
数据报传输不需要或不提供可靠或有序的数据传输。DTLS协议为有效负载数据保留此属性。由于传输数据的延迟敏感性,媒体流、互联网电话和在线游戏等应用程序使用数据报传输进行通信。当DTLS协议用于安全通信时,此类应用程序的行为保持不变,因为DTLS协议不会补偿丢失或重新排序的数据通信。
3. DTL概述
DTLS的基本设计理念是构建“基于数据报传输的TLS”。TLS不能直接用于数据报环境的原因很简单,数据包可能丢失或重新排序。TLS没有处理此类不可靠性的内部设施;因此,TLS实现在数据报传输上重新承载时中断。DTLS的目的是仅对TLS进行修复此问题所需的最小更改。尽可能地,DTLS与TLS相同。每当我们需要发明新的机制时,我们都试图以保留TLS风格的方式来实现。
不可靠性会在两个层面上给TLS带来问题:
1.TLS不允许对单个记录进行独立解密。由于完整性检查取决于序列号,如果未收到记录N,则记录N+1上的完整性检查将基于错误的序列号,因此将失败。(请注意,在TLS 1.1之前,没有显式IV,因此解密也会失败。)
2. TLS握手层假定握手消息是可靠传递的,如果这些消息丢失,则会中断。
本节的其余部分描述了DTLS用于解决这些问题的方法。
3.1. 不区分丢失的消息传递
在TLS的流量加密层(称为TLS记录层)中,记录不是独立的。有两种记录间依赖关系:
1.在记录之间保留加密上下文(流密码密钥流)。
2. 反重播和消息重新排序保护由包含序列号的MAC提供,但序列号在记录中是隐式的。
DTLS通过禁止流密码解决了第一个问题。DTLS通过添加显式序列号解决了第二个问题。
3.2. 为握手提供可靠性
TLS握手是一种锁步加密握手。信息必须按照规定的顺序发送和接收;任何其他顺序都是错误的。显然,这与重新排序和消息丢失不兼容。此外,TLS握手消息可能比任何给定的数据报都大,因此会产生IP碎片问题。DTL必须为这两个问题提供修复。

3.2.1. 丢包
DTLS使用一个简单的重传计时器来处理数据包丢失。下图使用DTLS握手的第一阶段演示了基本概念:
在这里插入图片描述
一旦客户机传输了ClientHello消息,它希望看到来自服务器的Helloverify请求。但是,如果服务器的消息丢失,客户端会知道ClientHello或HelloVerifyRequest已丢失并重新传输。当服务器接收到重新传输时,它知道重新传输。
服务器还维护一个重新传输计时器,并在该计时器过期时重新传输。
请注意,超时和重新传输不适用于HelloVerifyRequest,因为这需要在服务器上创建状态。HelloVerifyRequest被设计为足够小,以至于它本身不会被分割,从而避免了交叉处理多个HelloVerifyRequest的问题。

3.2.2. 重新排序
在DTLS中,每个握手消息在该握手中被分配一个特定的序列号。当对等方收到握手消息时,它可以快速确定该消息是否是它期望的下一条消息。如果是,那么它会处理它。如果没有,则在接收到所有以前的消息后,它会将其排队以备将来处理。

3.2.3. 消息大小
TLS和DTLS握手消息可能非常大(理论上最多为2^24-1字节,实际上是很多KB)。相反,如果不需要IP分段,UDP数据报通常限制在<1500字节。为了补偿此限制,每个DTLS握手消息可以在多个DTLS记录上分段,每个DTLS记录都旨在适合单个IP数据报。每个DTLS握手消息都包含片段偏移量和片段长度。因此,拥有握手消息的所有字节的接收者可以重新组合原始的未分段消息。

3.3. 重放检测
DTLS可选地支持记录重播检测。使用的技术与IPsec AH/ESP中的相同,通过维护接收记录的位图窗口。太旧而无法放入窗口的记录和以前收到的记录将被自动丢弃。重播检测功能是可选的,因为数据包复制并不总是恶意的,但也可能由于路由错误而发生。可以想象,应用程序可以检测重复分组并相应地修改其数据传输策略。

4.与TLS的区别
如第3节所述,DTLS有意与TLS非常相似。因此,我们没有将DTLS作为一个新协议来表示,而是将其表示为TLS1.2[TLS12]中的一系列增量。当我们没有明确指出差异时,DTL与[TLS12]中的相同。

4.1. 记录层
DTLS记录层与TLS 1.2非常相似。唯一的变化是在记录中包含一个显式序列号。此序列号允许收件人正确验证TLS MAC。DTLS记录格式如下所示:
在这里插入图片描述
与TLS 1.2记录中的类型字段等效的类型。
版本正在使用的协议的版本。本文档描述了DTLS版本1.2,它使用版本{254,253}。版本值254.253是DTLS版本1.2的1的补充。TLS和DTLS版本号之间的最大间隔确保了两个协议中的记录可以很容易区分。应该注意的是,DTL的未来在线版本号的值正在减少(而真实版本号的值正在增加)
历元每次密码状态更改时递增的计数器值。
sequence\u number此记录的序列号。
长度与TLS 1.2记录中的长度字段相同。与TLS 1.2一样,长度不应超过2^14。
片段与TLS 1.2记录的片段字段相同。
DTLS使用显式序列号,而不是隐式序列号,在记录的序列号字段中携带。序列号为每个历元单独维护,每个历元的序列号最初为0。例如,如果重新传输来自历元0的握手消息,则它可能在来自历元1的消息之后有一个序列号,即使来自历元1的消息
这是第一次传播。请注意,在握手过程中需要特别小心,以确保重新传输的消息使用正确的历元和键控材料。
如果连续执行几次握手,则线路上可能有多条具有相同序列号但来自不同密码状态的记录。“历元”字段允许收件人区分此类数据包。历元编号最初为零,并且在每次发送ChangeCipherSpec消息时递增。为了确保任何给定的序列/历元对都是唯一的,实现不得允许在TCP最大段生存期的两倍内重用相同的历元值。在实践中,TLS实现很少重新处理;因此,我们不认为这是一个问题。
请注意,由于DTLS记录可能会被重新排序,因此在第2个历元开始之后,可能会收到来自第1个历元的记录。一般来说,实现应该丢弃来自早期时代的数据包,但是如果数据包丢失导致明显的问题,它们可以选择保留来自早期时代的键控材料,直到为TCP[TCP]指定的默认MSL,以允许数据包重新排序。(注意,这里的意图是实现者使用IETF针对MSL的当前指导,而不是试图询问系统TCP堆栈正在使用的MSL。)在握手完成之前,实现必须接受来自旧时代的数据包。
相反,受新协商上下文保护的记录可能在握手完成之前被接收。例如,服务器可以发送完成的消息,然后开始传输数据。实现可以缓冲或丢弃此类数据包,但当通过可靠传输(例如,SCTP)使用DTL时,应在握手完成后对其进行缓冲和处理。请注意,TLS对何时发送数据包的限制仍然适用,并且接收方将数据包视为按照正确的顺序发送。特别是,仍然不允许在第一次握手完成之前发送数据。
请注意,在现有关联上的rehandshake的特殊情况下,即使尚未收到ChangeCipherSpec或Finished消息,只要rehandshake恢复现有会话或使用与现有关联完全相同的安全参数,也可以安全地立即处理数据包。在任何其他情况下,实现必须等待收到完成的消息,以防止降级攻击。
在TLS中,实现必须在允许序列号包装之前放弃关联或重新handshake。
类似地,实现必须不允许对历元进行包装,而是必须建立新的关联,如第4.2.8节所述终止旧关联。在实践中,实现很少在同一个通道上重复地重新握手,因此这不太可能成为问题。

类似地,实现必须不允许对历元进行包装,而是必须建立新的关联,如第4.2.8节所述终止旧关联。在实践中,实现很少在同一个通道上重复地重新握手,因此这不太可能成为问题。

4.1.1. 传输层映射
每个DTLS记录必须适合单个数据报。为了避免IP碎片,DTLS记录层的客户端应尝试调整记录的大小,使其符合从记录层获得的任何PMTU估计值。
请注意,与IPsec不同,DTLS记录不包含任何关联标识符。应用程序必须安排在关联之间进行多路传输。对于UDP,这可能是通过主机/端口号完成的。
多个DTLS记录可以放在一个数据报中。它们只是连续编码。DTLS记录帧足以确定边界。但是,请注意,数据报有效负载的第一个字节必须是记录的开头。记录不能跨越数据报.
有些传输,如DCCP[DCCP]提供它们自己的序列号。通过这些传输时,DTL和传输序列号都将出现。虽然这带来了少量的低效,但传输层和DTLS序列号的用途不同;因此,为了概念上的简单性,最好同时使用两个序列号。将来,可能会指定DTL的扩展,只允许在受限环境中使用一组序列号进行部署。
一些传输,如DCCP,为通过它们传输的流量提供拥塞控制。如果拥塞窗口足够窄,则DTLS握手重传可能被保持而不是立即传输,这可能导致超时和伪重传。当通过此类传输使用DTL时,应注意不要超出可能的拥塞窗口。[DCCPDTLS]定义了DTLS到DCCP的映射,该映射考虑了这些问题。

4.1.1.1. PMTU问题

  • DTLS记录帧扩展了数据报的大小,从而从应用程序的角度降低了有效的PMTU。
  • 在一些实现中,应用程序可能不会直接与网络通信,在这种情况下,DTLS堆栈可能会吸收ICMP[RFC1191]“数据报太大”指示或ICMPv6[RFC4443]“数据包太大”指示。
  • DTLS握手消息可能超过PMTU。
    为了处理前两个问题,DTLS记录层的行为应如下所述。
    如果可从底层传输协议获得PMTU估计值,则应将其提供给上层协议。特别地:
  • 对于UDP上的DTL,应允许上层协议获取IP层中维护的PMTU估计值。
  • 对于DCCP上的DTL,应允许上层协议获取PMTU的当前估计值。
  • 对于DCCP上的DTL,应允许上层协议获取PMTU的当前估计值。
    DTLS记录层应允许上层协议发现DTLS处理预期的记录扩展量。注意,由于块填充和DTLS压缩的潜在使用,这个数字只是一个估计值。
    如果存在传输协议指示(通过ICMP或通过[DCCP]第14节中的拒绝发送数据报),则DTLS记录层必须将错误通知上层协议。
    DTLS记录层不应通过[RFC1191]或[RFC4821]机制干扰上层协议执行PMTU发现。特别地:
  • 在底层传输协议允许的情况下,应允许上层协议设置DF位的状态(在IPv4中)或禁止本地分段(在IPv6中)。
  • 在底层传输协议允许的情况下,应允许上层协议设置DF位的状态(在IPv4中)或禁止本地分段(在IPv6中)。
    最后一个问题是DTLS握手协议。从DTLS记录层的角度来看,这只是另一个上层协议。然而,DTLS握手很少发生,并且只涉及少数往返;因此,握手协议PMTU处理比准确的PMTU发现更注重快速完成。为了在这些情况下允许连接,DTLS实现应遵循以下规则:
  • 如果DTLS记录层通知DTLS握手层消息太大,它应该立即尝试使用任何关于PMTU的现有信息对其进行分段。
  • 如果重复的重新传输不会导致响应,并且PMTU未知,则后续的重新传输应退回到较小的记录大小,并酌情对握手消息进行分段。本标准未规定退后前尝试的准确重传次数,但2-3次似乎合适。

4.1.2. 记录有效载荷保护(Record Payload Protection)
与TLS一样,DTL将数据作为一系列受保护的记录进行传输。本节其余部分将介绍该格式的详细信息。

4.1.2.1. MAC
DTLS MAC与TLS 1.2相同。但是,用于计算MAC的序列号不是使用TLS的隐式序列号,而是按照历元和序列号在导线上出现的顺序连接而成的64位值。请注意,DTLS历元+序列号的长度与TLS序列号的长度相同。
TLS MAC计算在协议版本号上参数化,在DTLS的情况下,协议版本号是有线版本,即DTLS 1.2的{254,253}。
请注意,DTLS和TLS MAC处理之间的一个重要区别是,在TLS中,MAC错误必须导致连接终止。在DTLS中,接收实现可以简单地丢弃有问题的记录并继续连接。这种变化是可能的,因为DTLS记录彼此之间的依赖性与TLS记录的依赖性不同。
一般来说,DTLS实现应该悄悄地丢弃具有坏MAC或其他无效的记录。他们可能会记录一个错误。如果DTLS实现在接收到带有无效MAC的消息时选择生成警报,则必须生成坏记录MAC警报。
具有致命级别并终止其连接状态。请注意,由于错误不会导致连接终止,因此DTLS堆栈比TLS堆栈更有效。因此,遵循[TLS12]第6.2.3.2节中的建议尤为重要。

4.1.2.2. 空或标准流密码
DTLS空密码的执行方式与TLS 1.2空密码完全相同。
TLS 1.2中描述的唯一流密码是RC4,它不能被随机访问。RC4不得与DTL一起使用。

4.1.2.3. 分组密码
DTLS分组密码加密和解密的执行与TLS 1.2完全相同。

4.1.2.4. AEAD密码
TLS 1.2引入了带有附加数据的认证加密(AEAD)密码套件。[ECCGCM]和[RSAGCM]中定义的现有AEAD密码套件可以与TLS 1.2一样与DTL一起使用。

4.1.2.5. 新密码套件
注册后,新的TLS密码套件必须说明它们是否适合DTLS使用,以及必须进行哪些修改(IANA注意事项见第7节)。

4.1.2.6. 反重放
DTLS记录包含一个序列号以提供重播保护。序列号验证应使用以下滑动窗口程序进行,从[ESP]第3.4.3节中借用。
建立会话时,此会话的接收器数据包计数器必须初始化为零。对于每个接收到的记录,接收方必须验证该记录包含的序列号是否与此会话期间接收到的任何其他记录的序列号不重复。这应该是在数据包与会话匹配后应用于数据包的第一次检查,以加快重复记录的拒绝。
通过使用滑动接收窗口拒绝重复项。(如何实现窗口是一个局部问题,但以下文本描述了实现必须展示的功能。)必须支持最小窗口大小32,但窗口大小为64是首选,应作为默认值使用。接收器可以选择另一个窗口大小(大于最小值)。(接收者不会将窗口大小通知发送者。)窗口的“右”边缘表示此会话上接收到的最高已验证序列号值。包含序列号低于窗口“左”边缘的记录将被拒绝。根据窗口内接收的数据包列表检查窗口内的数据包。[ESP]第3.4.3节描述了基于位掩码的有效检查方法。
如果接收到的记录落在窗口内并且是新的,或者如果数据包在窗口的右侧,则接收器进行MAC验证。如果MAC验证失败,接收器必须将接收到的记录视为无效而丢弃。仅当MAC验证成功时,才会更新接收窗口。

4.1.2.7. 处理无效记录
与TLS不同,DTLS在面对无效记录(例如,无效格式、长度、MAC等)时具有弹性。一般来说,无效记录应该被悄悄地丢弃,从而保留关联;但是,出于诊断目的,可能会记录错误。选择生成警报的实现必须生成致命级别的警报,以避免攻击者反复探测实现以查看其如何响应各种类型的错误的攻击。请注意,如果DTLS在UDP上运行,则任何执行此操作的实现都极易受到拒绝服务(DoS)攻击,因为UDP伪造非常容易。因此,不建议此类运输采用这种做法。
如果DTL通过抗伪造的传输(例如SCTP和SCTP-AUTH)传输,则发送警报更安全,因为攻击者很难伪造传输层不会拒绝的数据报。

4.2. DTLS握手协议
DTLS使用与TLS相同的所有握手消息和流,但有三个主要变化:
1.添加了无状态cookie交换以防止拒绝服务攻击。
2.修改握手报头以处理消息丢失、重新排序和DTLS消息碎片(以避免IP碎片)。
3.用于处理消息丢失的重传计时器。
除了这些例外,DTLS消息格式、流和逻辑与TLS 1.2相同。

4.2.1. 拒绝服务对策
数据报安全协议极易受到各种DoS攻击。有两起袭击事件特别令人关注:
1.攻击者可以通过发送一系列握手启动请求来消耗服务器上的过多资源,从而导致服务器分配状态并可能执行昂贵的加密操作。
2.攻击者可以通过发送带有伪造受害者来源的连接启动消息,将服务器用作放大器。然后,服务器将其下一条消息(在DTLS中是一条证书消息,可能非常大)发送到受害机器,从而使其泛滥。
为了对抗这两种攻击,DTLS借用了Photuris[Photuris]和IKE[IKEv2]使用的无状态cookie技术。当客户端向服务器发送ClientHello消息时,服务器可能会响应HelloVerifyRequest消息。此消息包含使用[PHOTURIS]技术生成的无状态cookie。客户端必须重新传输添加了cookie的ClientHello。然后,服务器验证cookie,并仅在握手有效时进行握手。这种机制迫使攻击者/客户端能够接收cookie,这使得使用伪造IP地址的DoS攻击变得困难。此机制不提供任何针对从有效IP地址装载的DoS攻击的防御。
在这里插入图片描述
server_version字段的语法与TLS中的相同。但是,为了避免在初始握手时进行版本协商的要求,DTLS 1.2服务器实现应该使用DTLS 1.0版本,而不管预期协商的TLS版本是什么。DTLS 1.2和1.0客户端必须仅使用版本来指示数据包格式(DTLS 1.2和1.0中的格式相同),而不是作为版本协商的一部分。特别是,DTLS 1.2客户端不能假设服务器在Helloverify请求中使用1.0版,因此服务器不是DTLS 1.2,或者它最终将协商DTLS 1.0而不是DTLS 1.2。
在响应Helloverify请求时,客户端必须使用与原始ClientHello中相同的参数值(版本、随机、会话id、密码套件、压缩方法)。服务器应使用这些值生成其cookie,并在收到cookie时验证它们是否正确。服务器在HelloVerifyRequest中必须使用与发送ServerHello时相同的版本号。收到ServerHello后,客户端必须验证服务器版本值是否匹配。为了避免多个Helloverify请求中的序列号重复,服务器必须使用ClientHello中的记录序列号作为Helloverify请求中的记录序列号。
注意:该规范将cookie大小限制增加到255字节,以提高将来的灵活性。对于以前版本的DTL,限制仍为32。
DTLS服务器应以这样的方式生成cookie,即可以在不保留服务器上任何每个客户端状态的情况下对cookie进行验证。一种技术是随机生成一个秘密并生成cookie,如下所示:
Cookie=HMAC(机密、客户端IP、客户端参数)
当接收到第二个ClientHello时,服务器可以验证Cookie是否有效,以及客户端是否可以在给定的IP地址接收数据包。为了避免在多个cookie交换的情况下重复序列号,服务器必须使用ClientHello中的记录序列号作为其初始ServerHello中的记录序列号。后续ServerHello仅在服务器创建状态后发送,并且必须正常递增。
对该方案的一种潜在攻击是,攻击者从不同的地址收集大量cookie,然后重用这些cookie来攻击服务器。服务器可以通过频繁更改机密值来抵御此攻击,从而使这些cookie无效。如果服务器希望合法客户端能够通过转换进行握手(例如,他们接收到一个包含机密1的cookie,然后在服务器更改为机密2后发送第二个ClientHello),则服务器可以有一个有限的窗口,在此期间它接受两个机密。[IKEv2]建议在cookie中添加一个版本号以检测此情况。另一种方法是尝试用两个秘密进行验证。
DTLS服务器应该在执行新握手时执行cookie交换。如果服务器在放大不成问题的环境中运行,则可以将服务器配置为不执行cookie交换。但是,默认情况下应执行交换。此外,服务器可以选择在会话恢复时不进行cookie交换。客户必须准备好在每次握手时交换cookie。
如果使用HelloVerifyRequest,则初始ClientHello和HelloVerifyRequest不包括在握手_消息(对于CertificateVerify消息)和验证_数据(对于完成的消息)的计算中。
如果服务器接收到带有无效cookie的ClientHello,则应将其视为没有cookie的ClientHello。如果客户端以某种方式获得了错误的cookie(例如,因为服务器更改了其cookie签名密钥),这将避免出现争用/死锁情况。
实现者注意:这可能会导致客户端使用不同的cookie接收多个HelloVerifyRequest消息。客户端应该通过发送一个新的ClientHello和一个cookie来响应新的Helloverify请求来处理这个问题。

4.2.2. 握手消息格式
为了支持消息丢失、重新排序和消息分段,DTLS修改了TLS 1.2握手头:
在这里插入图片描述
每一方在每次握手中发送的第一条消息始终具有消息_seq=0。每当生成每个新消息时,消息_seq值都会增加一。请注意,在rehandshake,这意味着HelloRequest将有消息_seq=0,而ServerHello将有消息_seq=1。重发消息时,使用相同的消息顺序值。例如:
在这里插入图片描述
然而,请注意,从DTLS记录层的角度来看,重传是一个新记录。此记录将有一个新的DTLSPlaintext.sequence_数值。
DTLS实现维护(至少在概念上)下一个接收顺序计数器。此计数器最初设置为零。接收到消息时,如果其序列号与next_receive_seq匹配,next_receive_seq将递增并处理该消息。如果序列号小于next_receive_seq,则必须丢弃该消息。如果序列号大于next_receive_seq,则实现应将消息排入队列,但可能会丢弃它。(这是一个简单的空间/带宽权衡)。

4.2.3. 握手消息碎片化和重组
如第4.1.1节所述,每个DTLS消息必须适合单个传输层数据报。但是,握手消息可能大于最大记录大小。因此,DTLS提供了一种机制,用于在多个记录上对握手消息进行分段,每个记录可以单独传输,从而避免IP分段。
在传输握手消息时,发送方将消息划分为一系列N个连续的数据范围。这些范围不得大于最大握手片段大小,并且必须共同包含整个握手消息。范围不应重叠。然后,发送方创建N条握手消息,所有消息都具有与原始握手消息相同的message_seq值。每个新消息都标有fragment_offset(先前片段中包含的字节数)和fragment_length(此片段的长度)。所有消息中的长度字段与原始消息的长度字段相同。未分段消息是一种退化情况,其片段_偏移量=0,片段_长度=长度。
当DTLS实现接收到握手消息片段时,它必须对其进行缓冲,直到它拥有整个握手消息。DTLS实现必须能够处理重叠的片段范围。这允许发送方在PMTU估计值发生变化时,以较小的片段大小重新传输握手消息。
请注意,与TLS一样,多个握手消息可以放在同一DTLS记录中,前提是有空间并且它们是同一航班的一部分。因此,有两种可接受的方法将两条DTLS消息打包到同一数据报中:在同一记录中或在单独的记录中。

4.2.4. 超时和重传
根据下图,DTLS消息被分组为一系列消息飞行。尽管每一段消息可能由许多消息组成,但为了超时和重新传输的目的,它们应被视为整体消息。
在这里插入图片描述
DTLS使用一个简单的超时和重传方案以及以下状态机。因为DTLS客户端发送第一条消息(ClientHello),所以它们在准备状态下启动。DTLS服务器在等待状态下启动,但缓冲区为空且没有重传计时器。
在这里插入图片描述
图3。DTLS超时和重传状态机
状态机有三种基本状态。
在准备状态下,实现执行准备下一次消息飞行所需的任何计算。然后,它将它们缓冲起来进行传输(首先清空缓冲区),并进入发送状态。
在发送状态下,实现传输消息的缓冲传输。消息发送后,如果这是握手中的最后一次飞行,则实现将进入完成状态。或者,如果实现希望接收更多消息,则设置重传计时器,然后进入等待状态。
有三种方法可以退出等待状态:
1.重传计时器过期:实现转换到发送状态,在发送状态下重传航班,重置重传计时器,并返回等待状态。
2.实现从对等方读取重新传输的航班:实现转换到发送状态,在发送状态下重新传输航班,重置重新传输计时器,并返回等待状态。这里的基本原理是,接收到重复消息可能是对等方计时器过期的结果,因此表明先前航班的一部分丢失。
3.实现将接收下一个消息段:如果这是最后一个消息段,则实现将转换为FINISHED。如果实现需要发送新航班,它将转换到准备状态。部分读取(无论是部分消息还是航班中的部分消息)不会导致状态转换或计时器重置。
因为DTLS客户端发送第一条消息(ClientHello),所以它们在准备状态下启动。DTLS服务器在等待状态下启动,但缓冲区为空且没有重传计时器。
当服务器需要重新握手时,它会从完成状态转换到准备状态以传输HelloRequest。当客户端接收到HelloRequest时,它将从完成转换为准备传输ClientHello。
此外,对于为[TCP]定义的至少两倍默认MSL,当处于完成状态时,传输最后一个航班的节点(普通握手中的服务器或恢复握手中的客户端)必须响应对等方最后一个航班的重新传输
最后一次航班的重发。这样可以避免最后一次航班丢失时出现死锁情况。这一要求也适用于DTLS 1.0,尽管在[DTLS1]中没有明确说明,但状态机始终需要正确运行。要知道为什么这是必要的,考虑一下如果服务器的完成消息丢失,普通握手中会发生什么:服务器相信握手完成了,但实际上不是。当客户端正在等待完成的消息时,客户端的重新传输计时器将启动,它将重新传输客户端完成的消息。这将导致服务器以自己完成的消息响应,完成握手。对于恢复的握手,同样的逻辑也适用于服务器端。
注意,由于分组丢失,即使另一方没有接收到第一方的完成消息,也有可能一方正在发送应用程序数据。实现必须丢弃或缓冲新纪元的所有应用程序数据包,直到它们收到该纪元的完成消息。实现可以将在接收到相应的完成消息之前接收到具有新纪元的应用程序数据视为重新排序或分组丢失的证据,并立即重新传输其最终飞行,从而缩短重新传输计时器。

4.2.4.1. 计时器值
虽然计时器值是实现的选择,但错误处理计时器可能导致严重的拥塞问题;例如,如果DTLS的许多实例提前超时,并且在拥挤的链路上重新传输过快。实现应使用1秒的初始计时器值(RFC 6298[RFC6298]中定义的最小值),并在每次重传时将该值加倍,最多不小于RFC 6298的最大值60秒。请注意,我们建议使用1秒的计时器,而不是3秒的RFC 6298默认计时器,以改善时间敏感应用程序的延迟。因为DTL只使用重传进行握手,而不使用数据流,所以对拥塞的影响应该是最小的。
实现应保留当前定时器值,直到发生无损耗传输,此时该值可重置为初始值。在长时间闲置(不少于当前计时器值的10倍)后,实施可能会将计时器重置为初始值。可能发生这种情况的一种情况是,在大量数据传输之后使用重新握手。

4.2.5. 更改密码规范
与TLS一样,ChangeCipherSpec消息在技术上不是握手消息,但为了超时和重新传输,必须将其视为与相关完成消息相同的航班的一部分。这会造成潜在的歧义,因为在消息丢失的情况下,无法明确地确定ChangeCipherSpec相对于握手消息的顺序。
这对于任何当前TLS模式都不是问题,因为在ChangeCipherSpec之前的预期握手消息集可以从握手状态的其余部分预测。然而,未来的模式必须注意避免产生歧义。

4.2.6. CertificateVerify和完成的消息
CertificateVerify和Finished消息的格式与TLS中的格式相同。散列计算包括整个握手消息,包括DTL特定字段:message_seq、fragment_offset和fragment_length。然而,为了消除对握手消息碎片的敏感性,必须计算完成的MAC,就像每个握手消息都作为单个碎片发送一样。请注意,在使用cookie交换的情况下,CertificateVerify或完成的MAC计算中不得包含初始ClientHello和HelloverIfy请求。

4.2.7. 警报消息
请注意,警报消息根本不会重新传输,即使它们发生在握手的上下文中。但是,如果再次收到违规记录(例如,作为重新传输的握手消息),通常会发出警报的DTLS实现应生成新的警报消息。实现应该检测对等方何时持续发送错误消息,并在检测到此类错误行为后终止本地连接状态。

4.2.8. 建立与现有参数的新关联
如果DTLS客户机-服务器对的配置方式使重复连接发生在同一主机/端口上,则客户机可能会自动放弃一个连接,然后使用相同的参数启动另一个连接(例如,重新启动后)。这将在服务器上显示为一次新的握手,历元=0。如果服务器认为它在给定的主机/端口上有一个现有关联,并且它接收到一个epoch=0 ClientHello,那么它应该继续进行一次新的握手,但在客户端通过完成cookie交换或完成一次完整的握手来证明其可达性之前,不能破坏现有关联包括传递可验证的已完成消息。在收到正确的完成消息后,服务器必须放弃以前的关联,以避免混淆具有重叠年代的两个有效关联。可达性要求可防止非路径/盲攻击者仅通过发送伪造的ClientHello来破坏关联。

4.3. 新语法概述
本节包括TLS 1.2和DTLS 1.2之间更改的数据结构规范。有关此语法的定义,请参见[TLS12]。

4.3.1. 记录层(Record Layer)
在这里插入图片描述

4.3.2. 握手协议
在这里插入图片描述

5.安全考虑
本文件描述了TLS 1.2的一个变体;因此,大多数安全注意事项与附录D、E和F中描述的TLS 1.2[TLS12]的安全注意事项相同。
DTLS提出的主要附加安全考虑是拒绝服务。DTLS包括一个cookie交换,旨在防止拒绝服务。但是,不使用此cookie交换的实现仍然容易受到DoS的攻击。特别是,不使用cookie交换的DTLS服务器可能被用作攻击放大器,即使它们本身没有遇到DoS。因此,DTLS服务器应该使用cookie交换,除非有充分的理由相信放大在其环境中不是威胁。客户必须准备好在每次握手时交换cookie。与TLS实现不同,DTLS实现不应通过终止连接来响应无效记录。详见第4.1.2.7节。

6.致谢
作者感谢Dan Boneh、Eu Jin Goh、Russ Housley、Constantine Sapuntzakis和Hovav Shacham对DTL设计的讨论和评论。感谢我们关于DTLS的原始NDSS论文[DTLS]的匿名NDSS审稿人的评论。另外,感谢史蒂夫·肯特的反馈,帮助澄清了许多要点。关于PMTU的章节摘自DCCP规范[DCCP]。Pasi Eronen对本规范进行了详细审查。彼得·圣安德烈在第8节中提供了变更清单。马克·奥尔曼、贾里·阿尔科、穆罕默德·巴德拉、迈克尔·德里科、阿德里安·法雷尔、乔尔·哈尔佩恩、特德·哈迪、查莉亚·考夫曼、佩卡·萨沃拉、埃里森·曼金、尼科斯·马夫罗吉安诺普洛斯、亚历克西·梅尔尼科夫、罗宾·塞格尔曼、迈克尔·图森、朱霍·瓦哈·赫图和弗洛里安·魏默也对该文件发表了有益的评论。

7.IANA考虑
本文档使用与TLS[TLS12]相同的标识符空间,因此不需要新的IANA注册表。为TLS分配新标识符时,作者必须指定它们是否适用于DTL。IANA修改了所有TLS参数注册表,以添加DTLS-OK标志,指示该规范是否可用于DTLS。在发布时,除以下内容外,所有[TLS12]注册均适用于DTL。注册的完整表格可在[IANA]上查阅。
在这里插入图片描述
本文档定义了一个新的握手消息hello_verify_request,其值已从[TLS12]中定义的TLS握手类型注册表中分配。IANA已指定值“3”。

  1. 自DTLS 1.0以来的变化
    在这里插入图片描述

9.工具书类
9.1. 规范性引用文件
在这里插入图片描述

9.2. 资料性引用
在这里插入图片描述
在这里插入图片描述


总结

关于技术方面的总结后面几篇在讲,在这里想分享的是最近研究RFC文献的感触,感觉越研究互联网技术越底层,越感觉凄凉,就是会发现底层的标准真的很难看到有中国建立的。在底层协议标准层面差距太大了,希望国内觉醒更多像华为一样的真正投入构建底层的公司。

感谢

感谢默默坚持的Coder,翻译了大量的RFC标准文献,大赞大赞。
链接: http://rfc2cn.com/index.html




                                                                                                             ---- 永不磨灭的番号:AK



在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AK@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值