随着我们日常生活中对智能设备和在线服务的依赖日益增加,数据传输的安全性变得尤为重要。想象一下,您正在进行一场关键的远程视频会议,或者智能家居设备正在向服务器发送敏感数据。在这些应用背后,正是DTLS 1.3协议在悄然守护着您的数据安全。无论是流媒体服务、物联网设备,还是在线游戏巨头,它们都依赖于DTLS 1.3的强大加密和低延迟能力,确保数据在不可靠的网络环境中也能安全传输。本文将深入解析DTLS 1.3握手过程中的每条消息,揭示这一协议的安全奥秘。
若无法复现本文章的结果,可参考此文章的教程:解决Wireshark无法解密DTLS1.3流量的方法
📢 文章末尾有该握手过程的拟人化解释
Client Hello :
- 这是客户端发送的第一个握手消息,用于开始 DTLS 握手。它包括了客户端支持的加密套件、协议版本等信息。
Client Hello
消息包括以下主要字段:- Version:客户端支持的最高协议版本。
- Random:客户端生成的随机数,用于后续密钥生成过程。
- SessionID Length:会话标识符,通常在新会话中为空。
- CipherSuites:客户端支持的加密套件列表,服务器会从中选择一个。
- CompressionMethods:支持的压缩方法,通常为无压缩。
- Extensions:扩展字段,包含客户端希望使用的扩展协议。
Client Hello的作用:
- 启动握手过程: - 第一个 Client Hello 消息是客户端向服务器发起连接的第一步。它标志着握手过程的开始,客户端通过该消息表达了希望建立安全连接的意图。
- 提供支持的加密参数: - 客户端在 Client Hello 消息中提供了其支持的加密套件、协议版本和扩展信息。这些信息使服务器能够选择合适的加密参数进行后续通信。
- 随机数生成: - Client Hello 消息中包含一个随机数(random 字段),该随机数用于后续的密钥生成过程,确保每次握手的唯一性和安全性。
Hello Retry Request :
- 这是服务器在接收到
Client Hello
后,发送给客户端的消息,此消息包含一个Cookie,服务器要求客户端重新发送Client Hello
。客户端必须在重发的Client Hello
消息中包含整个Cookie。此机制可有效防止恶意客户端发送大量的Client Hello
消息来消耗服务器资源.并且由于DTLS基于UDP,数据包可能会丢失或乱序。要求客户端重发Client Hello
消息也是为了确保数据传输的完整性。
Hello Retry Request
消息包括以下主要字段:
- Version: - 描述:该字段指定服务器支持的协议版本。尽管在DTLS1.3中不在用于版本协商,但仍保留以兼容旧版本。
- cipher_suite: - 描述:服务器选择的密码套件。客户端在收到此字段后,将根据此密码套件进行后续的密钥交换和加密。
- Compression_Method: - 描述:选择的压缩方法,通常在 DTLS 1.3 中不使用压缩,因此该字段通常为空。
- Extensions: - 描述:包含服务器希望客户端在重新发送 ClientHello 时考虑的扩展信息。这些扩展可能包括: - supported_versions:指示客户端支持的协议版本。- cookie:用于防止 DoS 攻击的 Cookie,客户端需要在重新发送的 ClientHello 中包含此 Cookie。
Hello Retry Request的作用:
- 参数协商:HelloRetryRequest 消息的主要目的是在客户端发送的 ClientHello 消息中,服务器发现参数不足以完成握手时,要求客户端重新发送 ClientHello。这样可以确保双方能够协商出兼容的参数。
- 防止 DoS 攻击:通过使用 Cookie,服务器可以确保只有有效的客户端会继续握手,从而降低潜在的拒绝服务(DoS)攻击风险。
Client Hello :
- 客户端响应
Hello Retry Request
,重新发送Client Hello
消息。这次的Client Hello
携带了服务器要求的Cookie,只有Cookie验证通过,服务器才会继续处理握手请求。
- 重发后的Client Hello消息包括以下主要字段:
- Version:客户端支持的最高协议版本。
- Random:客户端生成的随机数,用于后续密钥生成过程。
- SessionID Length:会话标识符,通常在新会话中为空。
- CipherSuites:客户端支持的加密套件列表,服务器会从中选择一个。
- CompressionMethods:支持的压缩方法,通常为无压缩。
- Extensions:扩展字段,包含客户端希望使用的扩展协议以及服务器要求的Cookie。
Client Hello 的作用
- 版本协商:客户端指明其支持的最高版本,服务器根据自身支持的版本进行选择。
- 加密套件协商:客户端列出其支持的加密套件,服务器从中选择一个进行后续的加密通信。
- 扩展协议协商:客户端可以请求使用特定的扩展协议,如 SRTP 密钥导出等,服务器则回应其支持的扩展。
Server Hello :
- 服务器对客户端的
Client Hello
做出响应,发送Server Hello
。这个消息包括了服务器选择的加密套件和协商的协议版本。
Server Hello
消息包括以下主要字段:- random:这是一个 32 字节的随机数,由服务器生成。这个随机数用于后续密钥生成过程。
- cipher_suite:这是服务器选择的加密套件,表示客户端和服务器之间将使用的加密算法和哈希算法。服务器从客户端提供的加密套件列表中选择一个,并在 Server Hello 消息中返回。
- extensions:这个字段包含了扩展信息,可能包括多种扩展,例如:
- supported_versions:声明服务器支持的 TLS 版本。
- key_share:包含服务器选择的密钥交换算法的相关信息。
- signature_algorithms:指示服务器支持的签名算法。
在
Server Hello
消息中提到’legacy_version’必须被忽略,服务器必须选择’supported versions’中列出的版本,并忽略任何未知的版本。因为在早期的DTLS和TLS版本中,‘legacy_version’用于指示客户端支持的最高协议版本。然而,许多服务器在处理版本协商时存在问题,导致了”version intolerance”现象,即服务器拒绝接受某些客户端请求,即使这些请求是可以接受的。所以DTLS1.3引入了‘supported versions’ 扩展,允许客户端明确指示它所支持的版本,并且服务器也使用这个扩展来指示它所选择的版本。
Server Hello 的作用
- 协商参数:
Server Hello
消息的主要作用是确认客户端在Client Hello
中所提出的参数,并提供服务器选择的加密套件和协议版本。 - 安全性:通过生成随机数,
Server Hello
消息确保了握手过程的安全性,防止中间人攻击和其他潜在的安全威胁。 - 密钥交换准备:
Server Hello
消息中的随机数和选定的加密套件为后续的密钥交换和加密通信奠定了基础。
Encrypted Extensions :
- 这是服务器发送的一个消息,此消息在服务器发送
Server Hello
后立即发送,包含加密的扩展信息,用于协商之后的连接参数。
Encrypted Extensions
消息包括以下字段:- Unified Header Bitmask:这是一个位掩码,用于表示数据包头的不同字段。这里0x2e表示以下几个字段: - 固定位(Fixed bits):0x1,表示这个字段必须为1。- CID字段(Connection ID):没有被设置,因此未使用。- 序列号大小(Sequence Number size):16位,表示这个字段占用16位。- 长度字段(Length field):存在,表示消息的长度被包括在内。- Epoch最低位(Epoch lowest-order bits):2,指示消息的epoch(epoch用来区分密钥更新的不同阶段,每次密钥发生变化时,epoch的值会递增.使用epoch值可避免混淆不同加密阶段的数据.)
- Sequence Number Suffix:序列号后缀,用于唯一标识每个DTLS数据包,这里是8076。
- Handshake Protocol: 握手协议
- Encrypted Extensions: 加密扩展信息
- Length: 此消息的总长度
- Message Sequence: 标识握手消息的顺序
- Fragment Offset and Length: 如果消息被分段,这些字段将显示其位置和大小。
Encrypted Extensions的作用:
- 保护敏感信息:
Encrypted Extensions
消息的主要作用是对某些扩展信息进行加密保护。通过在握手过程中加密这些扩展,可以防止潜在的中间人攻击和信息泄露。 - 确保握手的安全性:在
Server Hello
消息之后发送Encrypted Extensions
消息,确保在加密上下文建立后,所有后续的握手消息都受到保护。这增强了握手过程的安全性,防止了数据被篡改或窃听。
Certificate :
- 服务器发送它的证书给客户端,客户端使用该证书验证服务器的身份。
Certificate
消息包含以下主要字段:- Unified Header Bitmask: 位掩码,用于表示数据包头的不同字段
- Sequence Number Suffix:这是握手消息的序列号,用于消息的有序性和重传管理。
- serialNumber: 证书的序列号
- signature: 签名所用的算法(例如 sha256WithRSAEncryption)
- issuer: 证书签发者的信息
- validity: 有效期
****notBefore:这是证书开始生效的时间。也就是说,从这个时间点开始,证书被认为是有效的。 ****notAfter:这是证书失效的时间。到了这个时间点之后,证书将不再被认为是有效的。
- Subject: 证书持有者的信息
- **subjectPublicKeyInfo:**公钥信息
Certificate 的作用:
- 身份验证:
Certificate
消息的主要目的是提供服务器的身份验证。客户端通过验证服务器的数字证书,确保它连接到的是合法的服务器,而不是中间人或恶意服务器。 - 公钥传输: 证书中包含了服务器的公钥,客户端使用该公钥来加密后续的密钥交换信息,如 pre-master secret。这一过程确保了密钥交换的安全性。
- 链式验证:
Certificate
消息中的证书列表允许客户端进行链式验证。客户端会检查每个证书的有效性,包括签名、有效期和撤销状态,直到找到一个受信任的根证书。(在本地测试链式验证时,可以使用OpenSSL创建根CA和中间CA,然后签发服务器证书。具体步骤涉及创建根CA证书、中间CA证书,以及使用中间CA签发服务器证书,并最终将这些证书组合成证书链。)
Certificate Verify :
- 服务器发送此消息,以证明它拥有
Certificate
中所包含的私钥。这是通过对之前的握手消息签名来实现的。
Certificate Verify
消息包括以下主要字段:- Unified Header Bitmask:这是一个包含多项信息的位掩码,表示CID字段、序列号大小、长度字段等的存在性以及Epoch的最低位顺序。
- Sequence Number Suffix:这是握手消息的序列号,用于消息的有序性和重传管理。
- Handshake Protocol:指示这是一个握手协议消息,类型为
Certificate Verify
,用于验证客户端或服务器在握手过程中提供的证书的有效性。 - Signature Algorithm:使用的签名算法及其哈希函数。在这里显示的是
rsa_pss_rsae_sha256
。 - Signature:这部分包含了具体的签名值,验证了之前传输的所有消息的完整性和真实性。
Certificate Verify的作用:
- 身份验证:
Certificate Verify
消息用于证明服务器拥有与其数字证书中公钥相对应的私钥。这是通过对握手消息的哈希值进行签名来实现的。 - 握手完整性:此消息提供了到此为止握手过程的完整性保证。通过验证签名,接收方可以确认握手消息未被篡改。
- 发送时机:
Certificate Verify
消息必须在Certificate
消息之后立即发送,并且紧接在 Finished 消息之前。这确保了在握手的最后阶段,所有的身份验证和完整性检查都已完成。
Finished :
- 服务器发送
Finished
消息,表示服务器端的握手消息发送完成,之后的消息将受协商的加密协议保护。
Finished
消息包含以下主要字段:
- Unified header bitmask: 位掩码,用于指示DTLS记录层头部中的不同字段是否存在。
- Sequence Number Suffix: DTLS协议中的序列号,用于保证数据包的顺序和完整性。
- Length: 记录的总长度,这里为61字节。
- Handshake Protocol: Finished: 这表示这是一个DTLS握手协议中的
Finished
消息,用于完成握手过程并验证之前所有握手消息的完整性。 - Message Sequence: 消息序列号。
- Verify Data: 是通过对整个握手消息的哈希值进行计算而得出的,用于确保在握手过程中所有的信息都未被篡改。**Verify_Data 的计算过程:**1. 生成握手消息的哈希:- 首先,计算在握手过程中所有消息的哈希值。这包括
Client Hello
、Server Hello
、Certificate
、Certificate Verify
等所有握手消息。2. 使用主密钥生成 Verify_Data:- 使用伪随机函数(PRF)将主密钥、标签(如Finished
)和握手消息的哈希值作为输入,生成 Verify_Data。- 具体的计算公式为:$$ Verify Data=PRF(master secret, finished ,Hash(handshake messages)) $$
主密钥的生成过程
- 客户端和服务器的随机数: - 在握手的初始阶段,客户端和服务器各自生成一个随机数。客户端在其
Client Hello
消息中发送其随机数,而服务器在Server Hello
消息中发送其随机数。 - 密钥交换算法: - 客户端和服务器使用协商好的密钥交换算法(如 ECDHE 或 DHE)进行密钥交换。这一过程确保双方能够安全地生成共享的密钥材料。
- 预主密钥(Pre-Master Secret): - 在使用公钥加密的情况下,客户端会生成一个预主密钥,并使用服务器的公钥对其进行加密,然后发送给服务器。服务器使用其私钥解密该预主密钥。- 在使用 PSK(预共享密钥)时,双方直接使用 PSK 作为密钥材料。
- 生成主密钥: - 一旦双方都拥有预主密钥和各自的随机数,双方会使用伪随机函数(PRF)结合这些信息生成主密钥。具体的生成过程如下: - 使用 PRF 函数,将预主密钥、客户端随机数和服务器随机数作为输入,生成主密钥。- 生成的主密钥通常为 48 字节长。
Finished 的作用:
- 认证和完整性: -
Finished
消息用于验证握手过程的认证和完整性。它包含了一个 HMAC,该 HMAC 是对整个握手过程的哈希值计算得到的。- 这个 HMAC 使用了一个特殊的密钥,该密钥是从主密钥派生出来的。这确保了只有握手双方才能计算出正确的 HMAC。 - 握手完成的标志: - 当服务器发送
Finished
消息时,表明它已经成功地验证了客户端,并且握手过程已经完成。- 客户端在收到服务器的Finished
消息后,也会发送自己的Finished
消息,以确认握手的成功。 - 加密通信的开始: - 在
Finished
消息之后,双方就可以开始使用协商好的密钥进行加密通信了。-Finished
消息之前的所有握手消息都是明文传输的,而之后的消息都会被加密。 - 防止降级攻击: -
Finished
消息中的 HMAC 也用于防止降级攻击。如果 HMAC 验证失败,则表明握手过程中可能存在篡改,连接会被终止。
降级攻击的实现方式
- 监听和篡改通信: - 攻击者首先监听客户端与服务器之间的初始通信,获取客户端发送的
Client Hello
消息。该消息中包含了客户端支持的所有协议版本和加密套件。 - 伪造响应: - 攻击者在将
Client Hello
消息转发给服务器时,可能会修改该消息,删除高版本协议和强加密套件,只保留低版本协议和弱加密套件。 - 劫持握手过程: - 当服务器收到篡改后的
Client Hello
消息后,它会响应一个Server Hello
消息,通常选择一个较低版本的协议和较弱的加密套件。攻击者再将这个响应转发给客户端。 - 完成握手: - 客户端和服务器在降级后的协议和加密套件下完成握手。此时,攻击者可以利用较低的安全性进行中间人攻击或其他恶意活动。
Finished :
- 客户端在验证了服务器的
Finished
消息后,发送自己的Finished
消息,表示客户端的握手消息也发送完成。至此,握手过程结束,双方可以开始加密通信。
Finished
消息包含以下主要字段:
- Unified header bitmask: 位掩码,用于指示DTLS记录层头部中的不同字段是否存在。
- Sequence Number Suffix: DTLS协议中的序列号,用于保证数据包的顺序和完整性。
- Length: 记录的总长度,这里为61字节。
- Handshake Protocol: Finished: 这表示这是一个DTLS握手协议中的
Finished
消息,用于完成握手过程并验证之前所有握手消息的完整性。 - Message Sequence: 消息序列号。
- Verify Data: 是通过对整个握手消息的哈希值进行计算而得出的,用于确保在握手过程中所有的信息都未被篡改。
Finished 的作用:
与上一条
Finished
消息作用相同。
Acknowledgement :
- 这个消息可能是客户端对前一个
Finished
消息的确认,确保 DTLS 通道已经正确建立。
Acknowledgement
消息包含以下主要字段:
- Unified header bitmask: 位掩码,用于指示DTLS记录层头部中的不同字段是否存在。
- Sequence Number Suffix: DTLS协议中的序列号,用于保证数据包的顺序和完整性。
- Length: 记录的总长度,这里为61字节。
- Record Number: 由两个部分组成,即 Epoch 和 Sequence Number。
- Epoch: 指示记录号所属的DTLS时期。在这条消息中,Epoch为2,意味着这是会话的第二阶段。
- Sequence Number: 表示数据包的序列号,在这里是0,意味着这个
Acknowledgement
消息确认接收了Epoch 2中的第一个数据包。
Acknowledgement(ACK) 的作用:
- 确保消息的可靠传输: - 在基于 UDP 的 DTLS 1.3 中,数据包可能会丢失或乱序。ACK 机制通过让接收方确认已收到的消息,确保发送方知道消息是否成功传输。
- 防止消息丢失: - 如果发送方没有收到对某个消息的 ACK,它会重传该消息。这有助于防止消息在传输过程中丢失。
- 支持可靠的握手: - 在握手过程中,ACK 确保了每个消息都被成功传输。这对于建立安全的通信通道至关重要。
- 处理乱序消息: - 由于网络问题,消息可能会乱序到达。接收方使用
next_receive_seq
计数器来跟踪预期的下一个消息序号。如果收到的消息序号小于 **next_receive_seq
**,该消息会被丢弃。
握手过程拟人化解释
- UDP Packet : - Trigger Message:张三打了个电话给李四:“李四,现在该开始谈正事了。”
- Client Hello : - Client Hello:张三开始和李四说:“嗨,我是张三。我想和你商量一些事情。我喜欢这些交流方式(指的是加密套件和协议版本),你觉得怎么样?”
- Hello Retry Request : - Hello Retry Request:李四听完后,说:“张三,我觉得你说得不错,但在我们正式开始之前,我要先验证你是谁。请拿着这个‘通行证’(Cookie),然后再和我说一遍。”
- Client Hello (With Cookie) : - **Client Hello (With Cookie)**:张三拿到了李四给的“通行证”,然后又说:“李四,我重新整理了一下,带着你的通行证,我们可以继续聊了吗?”
- Server Hello : - Server Hello:李四点头表示:“好吧,张三,现在我确认了你的身份,我们就用这个加密方式和协议继续聊吧。”
- Encrypted Extensions : - Encrypted Extensions:李四接着说:“顺便说一下,我还有一些额外的想法,但这些是加密的,只有我们两个能懂。”
- Certificate : - Certificate:为了让张三放心,李四拿出身份证明:“这是我的身份证明(证书),你可以检查一下,确认我就是李四。”
- Certificate Verify : - Certificate Verify:李四补充道:“而且,我还要证明我确实拥有这个身份证。你看,我可以用它做些独特的签名。”
- Finished : - Server Finished:李四点点头表示:“好了,我这边的准备都完成了,现在我们可以开始真正的交流了。”
- Finished : - Client Finished:张三也点头回应:“好的,我也准备好了,我们可以安全地聊了。”
- Acknowledgement : - Acknowledgement:最后,张三轻轻拍了拍李四的肩膀:“好的,我明白了,一切都搞定了。”
版权归原作者 wenoukali 所有, 如有侵权,请联系我们删除。