深入探讨ClientHello

一、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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2025-01-05 13:23
下一篇 2025-01-05 13:23

相关推荐

  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • 深入了解scala-maven-plugin

    一、简介 Scala-maven-plugin 是一个创造和管理 Scala 项目的maven插件,它可以自动生成基本项目结构、依赖配置、Scala文件等。使用它可以使我们专注于代…

    编程 2025-04-25
  • 深入了解LaTeX的脚注(latexfootnote)

    一、基本介绍 LaTeX作为一种排版软件,具有各种各样的功能,其中脚注(footnote)是一个十分重要的功能之一。在LaTeX中,脚注是用命令latexfootnote来实现的。…

    编程 2025-04-25
  • 深入剖析MapStruct未生成实现类问题

    一、MapStruct简介 MapStruct是一个Java bean映射器,它通过注解和代码生成来在Java bean之间转换成本类代码,实现类型安全,简单而不失灵活。 作为一个…

    编程 2025-04-25
  • 深入探讨冯诺依曼原理

    一、原理概述 冯诺依曼原理,又称“存储程序控制原理”,是指计算机的程序和数据都存储在同一个存储器中,并且通过一个统一的总线来传输数据。这个原理的提出,是计算机科学发展中的重大进展,…

    编程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一个程序就是一个模块,而一个模块可以引入另一个模块,这样就形成了包。包就是有多个模块组成的一个大模块,也可以看做是一个文件夹。包可以有效地组织代码和数据…

    编程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r为前缀的字符串。r字符串中的反斜杠(\)不会被转义,而是被当作普通字符处理,这使得r字符串可以非常方便…

    编程 2025-04-25

发表回复

登录后才能评论