一、ClientHello消息
ClientHello是TLS握手的第一个步骤,它是客户端向服务器发送的一个消息,包含了客户端的TLS版本,加密套件的列表以及一个客户端生成的随机数。客户端与服务器通过ClientHello消息来商定加密套件以及其他参数来建立安全通信。
二、ClientHelloOuter
在TLS 1.3中,ClientHello被称为ClientHelloOuter,它会被发送到服务器上。ClientHelloOuter包含了客户端支持的加密套件列表、客户端Random、服务器名称指示(如果有)和扩展列表(包括supported_versions扩展)。
三、关闭ClientHello
如果客户端在握手过程中关闭了连接,它会发送一个空的ClientHello消息(仅包含TLS记录头),此时在服务器端的TLS握手中止。
四、ClientHello报文
ClientHello报文定义了在SSL或TLS握手过程中客户端向服务器提供的信息。至少包含如下字段:
struct { ProtocolVersion legacy_version = 0x0000; Random random; opaque legacy_session_id; CipherSuite cipher_suites; opaque legacy_compression_methods; Extension extensions; } ClientHello;
五、ClientHello长度为131
ClientHello消息5个字节的TLS头长度为5,其中3字节的TLS版本(0x0301或0x0303)和2字节的ClientHello消息长度共计5个字节。完整的ClientHello消息长度为131字节(包括TLS头),具体字段说明及扩展部分见后续小标题。
六、ClientHello消息各字段含义
1、legacy_version: 协议历史版本字段,表示当前客户端发送的TLS版本号。如果客户端支持的最高版本是TLS 1.3,则该字段必须为零字节(0x0000)表示没有支持的协议历史版本。
2、random:客户端生成的随机数,32字节长,其中4字节时间戳(10 byte timestamp us, 18 byte from an unpredictable source),其余28字节由安全随机数生成器生成。这些随机数与服务器端生成的随机数一起用于计算主密钥。
3、legacy_session_id: 此字段包含客户端连接的上一次会话的ID(如果有),这将允许会话重用。如果没有上一个会话ID,则长度为零字节(0x00)。
4、cipher_suites: 该字段包含加密套件列表,每个加密套件由一个16位的标识符标示,表示为两个字节。加密套件是客户端和服务器协商好的加密算法和密钥长度、用于交换密钥的算法。
5、legacy_compression_methods: 此字段包含客户端支持的压缩方法。仅有的一个有效值是零字节。
6、extensions: 此字段包含一个或多个加密套件扩展,例如SNI和ALPN等服务器名称指示和应用层协议协商。扩展的总长度由前两个字节表示。
七、ClientHello里面有哪些消息有哪些?
ClientHello消息中包含了多个字段,具体包括:
1、TLS版本: 握手协议版本号。
2、客户端和服务器生成的Random数。
3、该客户端上一次连接的会话ID(如果有)。
4、加密套件列表,客户端和服务器将应该共同支持的加密算法选出来。
5、压缩方法,表示客户端支持的压缩方法,通常该值为0x00表示不采用压缩。
6、扩展字段,包括SNI,ALPN等。
八、ClientHelloMayISpeak
ClientHelloMayISpeak是当客户端的TLS版本低于服务器支持的最低版本时,客户端允许发送的一条协商协议消息。如果服务器支持的最低版本为TLS 1.3,则客户端的ClientHelloMayISpeak应为 TLS 1.2 或更低版本的ClientHello消息。
九、ClientHello server_name
server_name是ClientHello扩展之一,用于指示客户端正试图连接到的服务器的主机名。对于使用共享IP地址的服务器而言,解析请求的主机名将使它能够知道要使用服务,由此可以在同一端口上支持多个虚拟主机。可以将以下代码添加到Python程序中,在发出HTTPS请求时获取server_name。
import ssl import socket context = ssl.create_default_context() with socket.create_connection(("www.google.com", 443)) as sock: with context.wrap_socket(sock, server_hostname="www.google.com") as ssock: print(ssock.version()) print(ssock.getpeercert())
结论
ClientHello是TLS握手的第一个步骤,包含了客户端的TLS版本,加密套件的列表以及一个客户端生成的随机数。客户端与服务器通过ClientHello消息来商定加密套件以及其他参数来建立安全通信。我们应该了解ClientHello报文的字段的含义,以帮助理解TLS握手,并充分利用扩展。同时,我们也可以通过server_name扩展为共享 IP 地址的服务器支持多个虚拟主机提供支持。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/311510.html