当前位置: 首页 > news >正文

Android 网络全栈攻略(四)—— TCPIP 协议族与 HTTPS 协议

Android 网络全栈攻略系列文章:
Android 网络全栈攻略(一)—— HTTP 协议基础
Android 网络全栈攻略(二)—— 编码、加密、哈希、序列化与字符集
Android 网络全栈攻略(三)—— 登录与授权
Android 网络全栈攻略(四)—— TCPIP 协议族与 HTTPS 协议
Android 网络全栈攻略(五)—— 从 OkHttp 配置来看 HTTP 协议
Android 网络全栈攻略(六)—— 从 OkHttp 拦截器来看 HTTP 协议一
Android 网络全栈攻略(七)—— 从 OkHttp 拦截器来看 HTTP 协议二

前面我们详细地介绍了 HTTP 协议,它是网络分层结构中,应用层最常用的协议之一。本篇我们将眼光放的更宏大一些,来看看网络是如何分层的,然后介绍 TCP/IP 分层模型中位于应用层下方的传输层中最核心的 TCP 协议,最后我们还要介绍基于 HTTP 但要比 HTTP 更安全的 HTTPS 协议。

1、TCP/IP 协议族

1.1 网络体系结构

开放系统互连参考模型 (Open System Interconnect,OSI)是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型,为开放式互连信息系统提供了一种功能结构的框架。OSI 采用分层结构化技术,共分为七层:物理层、数据链路层、网络层、 传输层、会话层、表示层、应用层

OSI 模型比较复杂且学术化,所以我们实际使用的 TCP/IP 模型,共分 4 层,链路层、网络层、传输层、应用层。两个模型之间的对应关系如图所示:

在这里插入图片描述

无论什么模型,每一个抽象层都是建立在低一层提供的服务上,并且为高一层提供服务。

1.2 分层的原因

分层主要是为了解决复杂系统的设计和管理问题。分层是计算机科学中经典的“分而治之”(Divide and Conquer)思想的体现,通过模块化、标准化和职责分离,实现以下目标:

  1. 降低复杂性:
    • 问题:网络通信涉及硬件、协议、路由、数据格式等多方面,直接设计一个整体的通信系统复杂度极高
    • 解决方案:将功能拆分为独立层级,每层只需关注自身职责(如物理层管电压信号,应用层管用户数据)
  2. 模块化开发与维护:
    • 独立演进:各层技术可独立升级(例如从 IPv4 升级到 IPv6 无需修改传输层协议)
    • 协作兼容:不同厂商只需遵循层级接口标准(如网卡厂商专注物理层,软件开发者专注应用层)
  3. 明确与复用职责:
    • 功能隔离:
      • 物理层:传输比特流(光纤、Wi-Fi)
      • 数据链路层:处理本地网络帧(MAC地址、以太网)
      • 网络层:路由与寻址(IP协议)
      • 传输层:端到端连接管理(TCP/UDP)
      • 应用层:用户交互(HTTP、FTP)
    • 代码复用:下层可为上层提供通用服务(例如 TCP 为所有应用提供可靠传输,无需重复实现)
  4. 标准化与互操作性:分层模型(如 OSI 或 TCP/IP)定义了各层接口规范,确保不同设备和协议兼容(例如 Windows 电脑通过 TCP/IP 与 Linux 服务器通信)
  5. 故障隔离与调试:
    • 快速定位问题:若网络不通,可逐层排查(例如先检查物理连接,再查 IP 配置,最后看防火墙规则)
    • 网络不稳定的应对:分层设计允许在特定层级处理错误(如传输层通过重传解决丢包,网络层通过重路由应对节点故障)

此外,分层也可以应对网络的不稳定性。

数据在网络传输时会自动选择最优路径,这种路径选择过程称为路由。由于网络具有天然不稳定性(如路由器损坏、网线被拔、停电等意外情况),需要通过接收方回执确认和超时重传来保证传输可靠性。当传输路径中的路由器损坏时,发送方在超时未收到回执后会选择其他路径重传数据。假设一个数据很大,传输时间很长,传输时间与失败风险成正比。那么在重传时如果又遇到路由损坏,就又要换路由重传这一个大数据,又要等很长时间。

因此,需要分块解决方案,仅需重传失败的数据块(接收方会记录已接收数据,避免重复处理),分块传输的额外成本要远远小于整体重传的额外成本,在显著降低重传数据量的同时,也降低了失败概率。

当然,也需要意识到,分层设计也是有代价的:

  • 性能损失:数据需逐层封装/解封装(例如 HTTP 数据需要添加 TCP 头、IP 头、以太网头)
  • 跨层优化困难:例如 QUIC 协议(HTTP/3)为了减少延迟,直接在 UDP 上实现传输层逻辑,打破了严格分层

1.3 TCP/IP 协议族

Transmission Control Protocol/Internet Protocol 的简写,中译名为传输控制协议/因特网互联协议,是 Internet 最基本的协议、Internet 国际互联网络的基础,由网络层的 IP 协议和传输层的 TCP 协议组成。协议采用了 4 层的层级结构。然而在很多情况下,它是利用 IP 进行通信时所必须用到的协议群的统称。也就是说,它其实是个协议家族,由很多个协议组成,并且是在不同的层, 是互联网的基础通信架构。

在这里插入图片描述

每个分层中,都会对所发送的数据附加一个首部,在这个首部中包含了该层必要的信息,如发送的目标地址以及协议相关信息。通常,为协议提供的信息为包首部,所要发送的内容为数据。在下一层的角度看,从上一层收到的包全部都被认为是本层的数据。网络中传输的数据包由两部分组成:一部分是协议所要用到的首部,另一部分是上一层传过来的数据。首部的结构由协议的具体规范详细定义。在数据包的首部,明确标明了协议应该如何读取数据。反过来说,看到首部,也就能够了解该协议必要的信息以及所要处理的数据。

在这里插入图片描述

各层的工作内容:

  1. 应用程序处理:首先应用程序会进行编码处理,这些编码相当于 OSI 的表示层功能;编码转化后,邮件不一定马上被发送出去,这种何时建立通信连接何时发送数据的管理功能,相当于 OSI 的会话层功能
  2. TCP 模块的处理:TCP 根据应用的指示,负责建立连接、发送数据以及断开连接。TCP 提供将应用层发来的数据顺利发送至对端的可靠传输。为了实现这一功能,需要在应用层数 据的前端附加一个 TCP 首部
  3. IP 模块的处理:IP 将 TCP 传过来的 TCP 首部和 TCP 数据合起来当做自己的数据,并在 TCP 首部的前端加上自己的 IP 首部。IP 包生成后,参考路由控制表决定接受此 IP 包的路由或主机
  4. 网络接口(以太网驱动)的处理:从 IP 传过来的 IP 包对于以太网来说就是数据。给这些数据附加上以太网首部并进行发送处理,生成的以太网数据包将通过物理层传输给接收端
  5. 网络接口(以太网驱动)的处理:主机收到以太网包后,首先从以太网包首部找到 MAC 地址判断是否为发送给自己的包,若不是则丢弃数据。如果是发送给自己的包,则从以太网包首部中的类型确定数据类型,再传给相应的模块,如 IP、ARP 等。这里的例子则是 IP
  6. IP 模块的处理:IP 模块接收到 数据后也做类似的处理。从包首部中判断此 IP 地址是否与自己的 IP 地址匹配,如果匹配则根据首部的协议类型将数据发送给对应的模块,如 TCP、UDP。这里的例子则是 TCP。 另外,对于有路由器的情况,接收端地址往往不是自己的地址,此时,需要借助路由控制表,在调查应该送往的主机或路由器之后再进行转发数据
  7. TCP 模块的处理:在 TCP 模块中,首先会计算一下校验和,判断数据是否被破坏。然后检查是否在按照序号接收数据。最后检查端口号,确定具体的应用程序。数据被完整地接收以后,会传给由端口号识别的应用程序
  8. 应用程序的处理:接收端应用程序会直接接收发送端发送的数据。通过解析数据,展示相应的内容

1.4 TCP 与 UDP

网际协议 IP 是 TCP/IP 中非常重要的协议。负责对数据加上 IP 地址(由发送它的主机的地址(源地址)和接收它的主机的地址(目的地址))和其他的数据以确定传输的目标。

而 TCP 和 UDP 都是传输层的协议,传输层主要为两台主机上的应用程序提供端到端的通信。

但是 TCP 和 UDP 最不同的地方是,TCP 提供了一种可靠的数据传输服务,TCP 是面向连接的,也就是说,利用 TCP 通信的两台主机首先要经历一个建立连接的过程,等到连接建立后才开始传输数据,而且传输过程中采用“带重传的肯定确认”技术来实现传输的可靠性。TCP 还采用一种称为“滑动窗口”的方式进行流量控制,发送完成后还会关闭连接。所以 TCP 要比 UDP 可靠的多。

UDP(User Datagram Protocol 的简称, 中文名是用户数据报协议)是把数据直接发出去,而不管对方是不是在接收,也不管对方是否能接收的了,也不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。

1.5 IP 地址与端口号

IP 地址(Internet Protocol Address)的全称叫作互联网协议地址,它的本义是为互联网上的每一个网络和每一台主机配置一个唯一的逻辑地址,用来与物理地址作区分。

所以 IP 地址用来识别 TCP/IP 网络中互连的主机和路由器。IP 地址基于逻辑,比较灵活,不受硬件限制,也容易记忆。

IP地址分为:IPv4 和 IPv6。IPv4 地址是由 32 位的二进制数组成,它们通常被分为 4 个“8位二进制数”,我们可以把它理解为 4 个字节,格式表示为:A.B.C.D。其中,A,B,C,D 这四个英文字母表示为 0-255 的十进制的整数。例:192.168.1.1。

IP 地址与 MAC 地址的区别:

  • IP 地址的设计是出于拓扑设计出来的,只要在不重复 IP 地址的情况下,它是可以随意更改的;而 MAC 地址是根据生产厂商烧录好的,它一般不能改动的
  • 最明显的区别就是长度不同,IPv4 地址的长度为 32 位,而 MAC 地址为 48 位
  • 寻址协议层不同。IP 地址应用于 OSI 模型的网络层,而 MAC 地址应用在 OSI 模型的数据链路层。 数据链路层协议可以使数据从一个节点传递到相同链路的另一个节点上(通过 MAC 地址),而网络层协议使数据可以从一个网络传递到另一个网络上(ARP 根据目的 IP 地址,找到中间节点的 MAC 地址,通过中间节点传送,从而最终到达目的网络)
  • 分配依据不同。IP 地址的分配是基于我们自身定义的网络拓扑,MAC 地址的分配是基于制造商

IP 地址的作用:

在这里插入图片描述

在传输层也有这种类似于地址的概念,那就是端口号。端口号用来识别同一台计算机中进行通信的不同应用程序。因此,它也被称为程序地址。一台计算机上同时可以运行多个程序。传输层协议正是利用这些端口号识别本机中正在进行通信的应用程序,并准确地将数据传输。

端口号的确定:

  • 标准既定的端口号:这种方法也叫静态方法。它是指每个应用程序都有其指定的端口号。但并不是说可以随意使用任何一个端口号。例如 HTTP、FTP、TELNET 等广为使用的应用协议中所使用的端口号就是固定的。这些端口号被称为知名端口号,分布在 0~1023 之间;除知名端口号之外,还有一些端口号被正式注册,它们分布在 1024~49151 之间,不过这些端口号可用于任何通信用途
  • 时序分配法:服务器有必要确定监听端口号,以让客户端程序访问服务器上的服务。但是使用服务的客户端没必要确定端口号。在这种方法下,客户端应用程序完全可以不用自己设置端口号,而全权交给操作系统进行分配。动态分配的端口号范围在 49152~65535 之间

1.6 TCP 三次握手

TCP 在进行数据传输之前,会通过三次握手建立一个虚拟连接,保证通信双方线路是通畅的,可以接收到对方发送的数据包,而不保证数据包的传输线路是固定的。

在这里插入图片描述

以上是三次握手的示意图:

  1. 客户端将标志位 SYN 置为 1,随机产生一个值 seq=J,并将该数据包发送给服务器端,客户端进入 SYN_SENT 状态,等待服务器端确认
  2. 服务器端收到数据包后由标志位 SYN=1 知道客户端请求建立连接,服务器端将标志位 SYN 和 ACK 都置为 1,ack=J+1,随机产生一个值 seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入 SYN_RCVD 状态
  3. 客户端收到确认后,检查 ack 是否为 J+1,ACK 是否为 1,如果正确则将标志位 ACK 置为 1,ack=K+1,并将该数据包发送给服务器端,服务器端检查 ack 是否为 K+1,ACK 是否为 1,如果正确则连接建立成功,客户端和服务器端进入 ESTABLISHED 状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了

确认对端发来的数据包时,都是将 ACK 标记为置位,并让 ack 的值等于对端发送的 seq + 1。这样对端在验证时检查接收的 ack 值为自己发送的 seq + 1 即可达到验证目的。

下面我们用 Wireshark 抓取三次握手的报文观察其具体内容:

请添加图片描述

第一个是客户端发送的请求连接的报文:

请添加图片描述

将 Syn 标记置位,且发送了一个随机产生的 Sequence Number。服务器会将这个 Sequence Number 加 1 作为 Acknowledge Number 的值,同时随机生成自己的 Sequence Number,将 Syn、Ack 两个标记置位:

请添加图片描述

最后客户端校验服务器发的 Acknowledge Number 的值是否为第一次握手时发给服务器的 Sequence Number + 1,如是则将 Ack 置位,同时将 Acknowledge Number 的值设置为服务端发送的 Sequence Number + 1:

请添加图片描述

为什么要三次握手?TCP 是可靠的传输控制协议,而三次握手是保证数据可靠传输又能提高传输效率的最小次数。TCP 的协议 RFC793 就谈到了原因:

为了实现可靠数据传输, TCP 协议的通信双方,都必须维护一个序列号, 以标识发送出去的数据包中,哪些是已经被对方收到的。

三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤。

如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

至于为什么不是四次,很明显,三次握手后,通信的双方都已经知道了对方序列号起始值,也确认了对方知道自己序列号起始值,第四次握手已经毫无必要了。

1.7 TCP 四次挥手

TCP 通过四次挥手断开连接,在 Socket 编程中,这一过程由客户端或服务端任一方执行 close 来触发。

由于 TCP 连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当甲方完成数据发送任务后,发送一个 FIN 给乙方来终止这一方向的连接,乙方收到一个 FIN 只是意味着不会再收到甲方数据了,但是乙方依然可以给甲方发送数据,直到这乙方也发送了 FIN 给甲方。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

请添加图片描述

过程如下:

  1. 主动关闭(active close)的一方调用 close 发送一个 FIN 分节,表示数据发送完毕,应用进程进入 FIN-WAIT-1(终止等待1)状态
  2. 接收到这个 FIN 的对端执行被动关闭(passive close),发出确认报文。这个 FIN 由 TCP 确认。因为 FIN 的接收意味着接收端应用进程在相应连接上再无额外数据可接收。接收端进入了 CLOSE-WAIT(关闭等待)状态,这时候处于半关闭状态,即主动关闭端已经没有数据要发送了,但是被动关闭端若发送数据,主动关闭端依然要接受。这个状态还要持续一段时间,也就是整个 CLOSE-WAIT 状态持续的时间。主动关闭端收到确认报文后进入 FIN-WAIT-2(终止等待2)状态
  3. 一段时间后,被动关闭的应用进程将调用 close 关闭它的套接字。这导致它的 TCP 也发送一个 FIN
  4. 接收这个最终 FIN 的原发送端 TCP(即执行主动关闭的那一端)确认这个 FIN 发出一个确认 ACK 报文,并进入了TIME-WAIT(时间等待)状态。注意此时 TCP 连接还没有释放,必须经过 2∗MSL 的时间后,当主动关闭端撤销相应的 TCB(传输控制块)后,才进入 CLOSED 状态

MSL(max segement lifetime,最长报文段寿命/最长分节生命期),是任何 IP 数据报能够在因特网中存活的最长时间,任何 TCP 实现都必须为 MSL 选择一个值。RFC 1122[Braden 1989] 的建议值是 2 分钟,不过源自 Berkelcy 的实现传统上改用 30 秒这个值。这意味着 TIME_WAIT 状态的持续时间在 1 分钟到 4 分钟之间。

被动关闭端只要收到了客户端发出的确认,立即进入 CLOSED 状态。同样,撤销 TCB 后,就结束了这次的 TCP 连接。可以看到,被动关闭端结束 TCP 连接的时间要比主动关闭端早一些。

为什么需要四次挥手?因为 TCP 是全双工模式。当一端发出 FIN 报文表示其没有数据要发送后,它仍可以接收数据,直到对端也发送 FIN 结束数据发送。

当然,特殊情况下可能只需要三次挥手即可。当主机 1 给主机 2 发送 FIN 报文告知对方数据已经发送完毕时,主机 2 需要给主机 1 发送 ACK 报文,倘若此时主机 2 的数据恰好已经发送完了,那么它需要发送一个 FIN 报文给主机 1,这时候就可能会出现,主机 2 将 FIN 和 ACK 报文合并成一个报文发送的情况,这种情况下就只进行了三次挥手。

2、HTTPS 协议

2.1 简介

HTTPS 全称为 Hypertext Transfer Protocol Secure 或 HTTP over SSL/TLS,是在 HTTP 协议基础上增加安全层的加密传输协议。其中,SSL(Secure Socket Layer,安全套接字层)是 TLS(Transport Layer Security,传输层安全)的前身,两者本质是同一技术标准的不同发展阶段。

TLS 是位于 HTTP(应用层)和 TCP(传输层)之间的独立安全层,本质上并非 HTTP 协议升级而是对 HTTP 协议的封装,在 HTTP 外层增加加密"罩子"。即 HTTPS 本质上是 HTTP + TLS 的组合代称,而非独立协议或 HTTP 的进化版本。

HTTPS 本身没有版本号,其包含的 HTTP 和 TLS 各自有独立版本。

工作流程为:

  • 连接建立:
    • TCP 三次握手建立传输层连接
    • TLS 握手协商加密参数、验证身份、生成密钥
    • 加密通信:使用对称密钥加密 HTTP 数据
  • 发送过程:HTTP → TLS 加密 → TCP 传输
  • 接收过程:TCP接收 → TLS 解密 → HTTP 处理

HTTPS 的原理在客户端和服务器之间用非对称加密协商出一套对称密钥,每次发送信息之前将内容加密,收到之后解密,达到内容的加密传输。采用混合加密策略,可以分为两个阶段:

  • 协商阶段:使用非对称加密协商对称密钥
  • 通信阶段:使用对称加密进行实际数据传输

采用混合加密的理由是非对称加密计算复杂导致性能问题,混合方案兼顾安全与效率。

2.2 建立 HTTPS 连接

HTTPS 连接专用于加密/解密,不负责数据传输稳定性(由 TCP 保证),技术上通过 Socket 接口实现,类似 TCP 连接但专注于安全上下文管理。

HTTPS TLS 1.2 连接建立的大致流程如下(TLS 1.3 步骤有优化):

  • 客户端发起 TLS 连接请求
  • 服务器给出响应,返回数字证书
  • 客户端验证证书真实性
  • 客户端信任服务器后,通过非对称加密协商对称密钥
  • 使用对称密钥开始通信,建立加密通信通道

下面开始介绍详细的握手流程。

客户端发送 Client Hello

客户端先发出一个 Client Hello 消息:

在这里插入图片描述

该消息包含以下主要信息:

  • 初始字节:客户端发送的第一个字节值为 1,表示 TLS 连接请求
  • 握手协议类型:Handshake Protocol,握手协议有多种类型,比如现在说到的 Client Hello 就是其中一种,其类型值为 1。后续会看到其他类型,如 Server Hello(2)、Certificate(11)、ClientKeyExchange(16) 等
  • 客户端支持的 TLS 版本:服务器收到后,如果其支持多个版本,会从中选择一个双方都支持的版本,如果都不支持则加密建立连接失败
  • 客户端支持的加密套件:包括对称加密算法、非对称加密算法以及 hash 算法。服务器也是从中选择一个使用
  • 客户端随机数:32 字节,必须保证真正的随机性,防止被猜测或推演。客户端本地保留副本同时发送给服务器,用于后续密钥生成等安全计算过程

这些信息的报文内容如下:

请添加图片描述

服务器发送 Server Hello

服务器收到客户端发来的 Client Hello 后,会发送一个 Server Hello 作为回应:

在这里插入图片描述

回应的主要内容是选定的 TLS 版本、加密套件、服务端随机数、证书信息等:

请添加图片描述

注意,服务器发给客户端的随机数,与客户端发给服务器的随机数不同。随机数交换是双向的,客户端和服务端各自保留自己生成的随机数,并接收对方发来的随机数。

这一步中比较重要的是发送了证书信息,其中 Certificates 中包含两个证书,第一个是服务器证书,第二个是服务器证书的签发机构的证书:

请添加图片描述

展开证书信息:

请添加图片描述

我们逐个字段来解读:

  1. 证书消息整体结构:
    • Handshake Protocol: Certificate:TLS 握手协议中的证书消息,表示服务器正在向客户端发送证书链
    • Handshake Type: Certificate (11):握手消息类型为“证书”,类型代码为 11(TLS 协议定义的标准值)
    • Length: 3759:整个证书消息的总长度(包含所有证书及元数据)
    • Certificates Length: 3756:证书链中所有证书的总字节数(3756 字节)
  2. 单个证书结构:服务器通常会发送两个证书(形成证书链),第一个是服务器证书,第二个是服务器证书的签发机构的证书。每个证书包含以下关键字段:
    • 证书元数据:
      • Certificate Length: 1994:当前证书的字节长度,第一个证书为 1994
      • Certificate […]: 308207c6…:证书的二进制内容,采用ASN.1 DER编码的十六进制格式
    • 证书核心字段:
      • version: v3 (2):证书版本号,v3 是当前广泛使用的版本(支持扩展字段)
      • serialNumber: 0x330000…:证书的唯一序列号(由 CA 分配,十六进制格式)
      • signature (sha256WithRSAEncryption):证书的签名算法:SHA-256 哈希 + RSA 加密
      • issuer:证书颁发者(CA)的信息,例如第一个证书有两个字段:
        id-at-commonName=Microsoft Secure Server CA 2011(CA 证书名称)
        id-at-organizationName=Microsoft Corporation(组织名称)
      • validity:证书的有效期,包含起止时间(图中未展开,通常为 UTC 时间)
      • subject:证书持有者的信息(服务器或实体),例如域名或组织名称
      • subjectPublicKeyInfo:证书中的公钥信息,包含:
        • algorithm (rsaEncryption):公钥算法(如 RSA)
        • modulus: 0x00dd303e…:RSA公钥的模数(大整数,用于加密)
        • publicExponent: 65537:RSA公钥的指数(通常为固定值 0x10001
    • 扩展字段:证书的扩展功能字段,常见扩展包括
      • Subject Alternative Name (SAN):证书支持的域名列表(如 DNS:example.com
      • Key Usage:密钥用途(如加密、签名)
      • Extended Key Usage:扩展用途(如TLS服务器认证)
      • CA信息:标识是否可作为 CA 证书
      • CRL分发点:证书吊销列表的URL
      • OCSP:在线证书状态检查地址

需要注意两个证书的 issuer 字段表示该证书的签发机构,比如:

  • 第一个证书,服务器证书的 issue 的 id-at-commonNameMicrosoft Secure Server CA 2011,意味着服务器证书是由中间 CA Microsoft Secure Server CA 2011 签发的
  • 第二个证书,也就是中间 CA 的证书,它是由根 CA Microsoft Root Certificate Authority 2011 签发的

我们需要清楚的是证书链的主要信息包含:服务器证书、服务器证书签名、证书签发机构的证书、证书签发机构的证书的签名、证书签发机构的签发机构的证书

每一级证书都包公钥、主机名、地区信息,其中最重要的是公钥。

客户端验证证书

公钥会被用于客户端向服务器发送正式数据时加密数据所用,因此其非常重要,再加上网络的危险与不可信性,客户端拿到公钥后的第一件事不是使用它加密要发送的数据,而是要对证书进行复杂验证(具体验证过程后续讲解),确保证书真实有效。主要验证两点:

  1. 验证证书的合法性:通过服务器传来的证书链,验证如下内容:
    • 颁发者可信性:证书必须由可信的证书颁发机构(CA)签发,客户端需验证整个证书链是否最终链接到本地信任的根 CA(如预置在操作系统或浏览器中的根证书)
    • 有效期检查:证书的起止时间(validity字段)必须合法,未过期且未提前生效
    • 签名完整性:用上级 CA 的公钥验证证书签名(如 sha256WithRSAEncryption)是否有效,确保证书未被篡改
    • 密钥用途匹配:证书的扩展字段(如 Key Usage)必须包含 TLS Web Server Authentication,证明该证书是用于服务器身份验证的
  2. 验证服务器主机名:客户端会检查证书中的域名是否与用户实际访问的服务器主机名一致,这是为了防止以下风险:
    • 中间人攻击(MITM):攻击者可能伪造一个合法的证书(如盗用 CA 私钥签发),但证书中的域名与目标服务器不一致。若客户端不验证主机名,攻击者可能将流量劫持到自己的服务器
    • 域名伪装:例如,用户访问 example.com,但服务器返回的证书是为 evil.com 签发的,需通过主机名验证拦截此类异常

证书链通常就是三级:服务器证书、中间 CA 证书、根 CA 证书。因为你总要相信一个证书,否则证书链可能会很长,无限递归,这个被相信的证书就是根 CA 证书。而相信根 CA 的前提,是你无条件相信设备制造商在安装设备系统(Windows、Mac、Android、iOS)时内置的信任机构。

以 Windows 为例,按照如下步骤查看 Windows 内置的证书:

在这里插入图片描述

你会发现我们上面抓包中看到的根 CA 机构 Microsoft Root Certificate Authority 2011 就存在于 Windows 内置的证书列表中:

在这里插入图片描述

客户端发送密钥

客户端信任服务器后,通过非对称加密协商对称密钥,实际上就是生成一个随机密钥 X 并用证书的公钥加密后发送给服务器,报文如下:

在这里插入图片描述

报文具体内容:

请添加图片描述

实际上是发送了三个 TLS 报文:

  1. 客户端用服务器证书公钥加密的随机数称为 pre-master secret(即上图中的 Client Params),将其发送给服务器,这样 CS 两端就都有客户端随机数、服务器随机数与 pre-master secret,它们三个通过算法计算最终会共同生成 master secret
  2. 客户端通知服务器将使用加密通信,主要是告知服务器切换加密方式
  3. 客户端发送结束消息:将 Client Hello、Server Hello、服务器证书、pre-master secret、加密通信通知等前五步握手消息综合加密,并附加 HMAC 校验值

这里能体现出 CS 两端随机数的作用,就是防御重放攻击。通过服务器每次返回不同的随机数,使之前截获的通信数据失效。使用三个随机数:客户端随机数、服务器随机数和 pre-master secret 共同保证安全性。而且这三个随机数通过算法生成 master secret,而 master secret 会生成四个密钥:

  • 客户端加密密钥
  • 服务端加密密钥
  • 客户端 MAC secret
  • 服务端 MAC secret

双方都能独立计算出相同密钥,确保通信同步。

服务器发送结束消息

最后服务器要告知客户端将使用加密通信以及发送一个结束消息:

在这里插入图片描述

具体内容:

在这里插入图片描述

实际上与上一步中客户端发送的后两条消息类似的:

  • Change Cipher Spec:通知客户端之后的消息开始启用加密参数
  • Encrypted Handshake Message:服务端 SSL 协商成功结束,发送握手信息验证报文确保消息完整性

发送完这条消息后,服务端就可以开始发送加密信息了。

2.3 总结

一个完整的 HTTPS 连接通信的过程示意图如下:

请添加图片描述

再算上传输层的 TCP 过程,完整的报文过程如下:

请添加图片描述

http://www.lqws.cn/news/596539.html

相关文章:

  • Linux基本命令篇 —— grep命令
  • 基于ApachePOI实现百度POI分类快速导入PostgreSQL数据库实战
  • opencv使用 GStreamer 硬解码和 CUDA 加速的方案
  • 【cesium】基于vue-cesium开发地理空间分析应用
  • 在 Vue 3 中,如果需要显示 HTML 标签,可以使用 v-html 指令
  • android stdio 创建 mediaplayertest
  • 零信任安全管理系统产品对比介绍
  • 小米YU7使用UWB技术,厘米级定位精准迎宾,安全防破解无感控车
  • .NET测试工具Parasoft dotTEST:全兼容RMS的测试解决方案
  • 538. 把二叉搜索树转换为累加树
  • 清理 Docker 缓存占用
  • Vue 3.x 使用 “prerender-spa-plugin ” 预渲染实现网站 SEO 优化
  • 透视变换、仿射变换
  • webpack的作用是什么,谈谈你对它的理解?
  • MySQL索引失效问题
  • vue-35(使用 Jest 和 Vue Test Utils 设置测试环境)
  • 折扣点餐对接api应该如何选择?
  • React Native 0.79.4 中 [RCTView setColor:] 崩溃问题完整解决方案
  • 在线租房平台源码+springboot+vue3(前后端分离)
  • 模型部署与推理--利用python版本onnxruntime模型部署与推理
  • C++面试题精讲系列之数组排序
  • raid的介绍和raid对比 和 lvm 的介绍和使用 扩容
  • Qt 实现Opencv功能模块切换界面功能
  • 线性规划模型
  • 【V5.0 - 视觉篇】AI的“火眼金睛”:用OpenCV量化“第一眼缘”,并用SHAP验证它的“审美”
  • TensorFlow内核剖析:分布式TensorFlow架构解析与实战指南
  • 通往物理世界自主智能的二元实在论与罗塞塔协议
  • 软件测试-持续集成
  • DVWA靶场通关笔记-文件包含(Medium级别 9种渗透方法)
  • Nebula Graph Meta 服务无法启动