在 TLS 协议中解析扩展问候消息的正确方法是什么?
What is the correct way to parse extended hello messages in TLS protocol?
根据RFC 5246(定义 TLS 协议版本 1.2)
第 18 页:
The record layer fragments information blocks into TLSPlaintext
records carrying data in chunks of 2^14 bytes or less. Client
message boundaries are not preserved in the record layer (i.e.,
multiple client messages of the same ContentType MAY be coalesced
into a single TLSPlaintext record, or a single message MAY be
fragmented across several records).
第 40 页上写着:
TLS allows extensions to follow the compression_methods field in an
extensions block. The presence of extensions can be detected by
determining whether there are bytes following the compression_methods
at the end of the ClientHello. Note that this method of detecting
optional data differs from the normal TLS method of having a
variable-length field, but it is used for compatibility with TLS
before extensions were defined.
我从这段话中了解到的是,当我解析完一个ClientHello
消息后,我应该将它的大小与封装记录层消息的TlsPlaintext.length
字段进行比较,看是否有记录层消息末尾的任何额外字节,如果有,将它们解释为 Extension
结构。
这对于我测试我的应用程序的一些 TLS 流量样本实际上工作正常,但对于其他一些则失败(即它无法检测 wireshark 可以检测的消息)。当我使用 wireshark 查看有问题的数据包时,它看起来像是几个握手消息组合成一个握手消息。这些是带有扩展名的 ServerHello
(看起来完全像 ClientHello
),Certificate
和 ServerHelloDone
消息。
当 Hello 消息被封装在单个握手消息中时,检测 Hello 扩展很容易,但我不明白当存在其他握手消息时,如何在 hello 消息之后检测扩展部分的存在和边界他们之后是相同的消息。
任何关于如何解析这些数据包的帮助或建议将不胜感激。
属于(hanshake 协议、更改密码规范协议、警报协议、其他协议)的每个 TLS 消息都在记录层协议内(或之上)发送。看看这个:https://technet.microsoft.com/en-us/library/cc767139.aspx
记录层协议将提供:
- 内容类型(1 个八位字节)
- 版本(2 个八位字节)
- 长度(2 个八位字节)
每条 TLS 消息都将以这些字段开头,即使您在同一 TCP 段的负载中看到许多 SSL 消息也是如此。您可以将这些消息解析为单独的 TLS 消息。
SSL Record Protocol中的Length会给你上层协议报文的总长度。如果它是作为握手协议一部分的 Hello 消息,它将包含扩展。该字段还可以让您确定边界或许多 TLS 消息聚集在一起。
在 Hello 消息的情况下,在压缩方法字段之后,您有 2 个八位字节指示扩展长度。扩展包含在包含 Hello 消息的 SSL 记录协议的长度字段中。它们也包含在同一 Hello 消息的长度中。
在 SSL 记录层之后,不同协议的每条消息都以自己的方式解析:
- 更改密码规范协议:始终为 1 个八位字节
- 握手协议:TLV(类型、长度、值)
- 警报协议:2 个八位字节(级别、警报)
- HTTP 或其他...
因此,当您有许多 TLS 消息聚集在同一个 TCP 段中时,您总是:
Offset = 0
While more data (based on TCP payload length):
Read first 5 octets at Offset
Obtain Length field (Assign to MessageLength, Offset += 5)
Process first TLS message from Offset, with length MessageLength
Offset += MessageLength
希望我能正确解决您的问题...
根据RFC 5246(定义 TLS 协议版本 1.2)
第 18 页:
The record layer fragments information blocks into TLSPlaintext records carrying data in chunks of 2^14 bytes or less. Client message boundaries are not preserved in the record layer (i.e., multiple client messages of the same ContentType MAY be coalesced into a single TLSPlaintext record, or a single message MAY be fragmented across several records).
第 40 页上写着:
TLS allows extensions to follow the compression_methods field in an extensions block. The presence of extensions can be detected by determining whether there are bytes following the compression_methods at the end of the ClientHello. Note that this method of detecting optional data differs from the normal TLS method of having a variable-length field, but it is used for compatibility with TLS before extensions were defined.
我从这段话中了解到的是,当我解析完一个ClientHello
消息后,我应该将它的大小与封装记录层消息的TlsPlaintext.length
字段进行比较,看是否有记录层消息末尾的任何额外字节,如果有,将它们解释为 Extension
结构。
这对于我测试我的应用程序的一些 TLS 流量样本实际上工作正常,但对于其他一些则失败(即它无法检测 wireshark 可以检测的消息)。当我使用 wireshark 查看有问题的数据包时,它看起来像是几个握手消息组合成一个握手消息。这些是带有扩展名的 ServerHello
(看起来完全像 ClientHello
),Certificate
和 ServerHelloDone
消息。
当 Hello 消息被封装在单个握手消息中时,检测 Hello 扩展很容易,但我不明白当存在其他握手消息时,如何在 hello 消息之后检测扩展部分的存在和边界他们之后是相同的消息。
任何关于如何解析这些数据包的帮助或建议将不胜感激。
属于(hanshake 协议、更改密码规范协议、警报协议、其他协议)的每个 TLS 消息都在记录层协议内(或之上)发送。看看这个:https://technet.microsoft.com/en-us/library/cc767139.aspx
记录层协议将提供:
- 内容类型(1 个八位字节)
- 版本(2 个八位字节)
- 长度(2 个八位字节)
每条 TLS 消息都将以这些字段开头,即使您在同一 TCP 段的负载中看到许多 SSL 消息也是如此。您可以将这些消息解析为单独的 TLS 消息。
SSL Record Protocol中的Length会给你上层协议报文的总长度。如果它是作为握手协议一部分的 Hello 消息,它将包含扩展。该字段还可以让您确定边界或许多 TLS 消息聚集在一起。
在 Hello 消息的情况下,在压缩方法字段之后,您有 2 个八位字节指示扩展长度。扩展包含在包含 Hello 消息的 SSL 记录协议的长度字段中。它们也包含在同一 Hello 消息的长度中。
在 SSL 记录层之后,不同协议的每条消息都以自己的方式解析:
- 更改密码规范协议:始终为 1 个八位字节
- 握手协议:TLV(类型、长度、值)
- 警报协议:2 个八位字节(级别、警报)
- HTTP 或其他...
因此,当您有许多 TLS 消息聚集在同一个 TCP 段中时,您总是:
Offset = 0
While more data (based on TCP payload length):
Read first 5 octets at Offset
Obtain Length field (Assign to MessageLength, Offset += 5)
Process first TLS message from Offset, with length MessageLength
Offset += MessageLength
希望我能正确解决您的问题...