HTTPS 中 TLS 协议详细过程 + 数字证书/签名深度解析

HTTPS 的核心是 "HTTP + TLS/SSL" ,其中 TLS(Transport Layer Security,传输层安全)是保障通信安全的核心协议(SSL 是其前身,已被淘汰)。TLS 的核心目标是:在不安全的网络(如互联网)中,为客户端和服务器建立加密、认证、防篡改的通信通道

本文将从 TLS 完整握手流程(以 TLS 1.3 为主,兼容 TLS 1.2 差异)、数字证书的结构与作用、数字签名的原理与验证 三个维度,进行底层细节拆解,兼顾理论与工程实现逻辑。

一、TLS 协议核心目标与核心技术

在讲解流程前,先明确 TLS 要解决的核心问题及依赖的关键技术:

1.1 核心目标(CIA 三元组)

  • 机密性(Confidentiality):通信内容仅对客户端和服务器可见,中间攻击者无法窃取(依赖对称加密、非对称加密)。
  • 完整性(Integrity):通信内容在传输过程中未被篡改(依赖哈希函数、数字签名)。
  • 认证性(Authenticity):确认对方是真实的通信对象(而非中间人伪装,依赖数字证书、数字签名)。

1.2 核心技术栈

技术类型 作用 代表算法
非对称加密 密钥交换、数字签名 RSA、ECDH(椭圆曲线 Diffie-Hellman)、ECDSA
对称加密 加密通信数据(效率高) AES-GCM、ChaCha20-Poly1305
哈希函数 生成数据摘要(防篡改、签名基础) SHA-256、SHA-384
数字证书 绑定服务器身份与公钥(解决"公钥信任") X.509 标准
数字签名 验证数据来源合法性、防篡改 RSA-SHA256、ECDSA-SHA384

1.3 关键概念铺垫

  • 对称加密:加密和解密用同一把密钥(如 AES),速度快,但密钥协商过程需保障安全(不能明文传输)。
  • 非对称加密:有公钥(公开)和私钥(保密),公钥加密的内容仅私钥可解,私钥签名的内容仅公钥可验(如 RSA),速度慢,适合小数据传输(如密钥交换)。
  • 密钥交换:TLS 握手的核心是"安全协商出一把临时对称密钥",后续通信均用该密钥加密(对称加密效率高)。
  • 会话复用:避免每次连接都完整握手(耗时),通过会话票据(Session Ticket)或会话 ID 复用已协商的密钥。

二、TLS 完整握手流程(TLS 1.3 详解,对比 TLS 1.2)

TLS 握手是 HTTPS 建立连接的核心阶段,TLS 1.3 是目前最新、最安全、最高效的版本(2018 发布),相比 TLS 1.2 大幅简化流程、缩短延迟。以下分步骤拆解 TLS 1.3 标准握手流程(无会话复用场景),并标注与 TLS 1.2 的关键差异。

整体流程概览

TLS 1.3 握手仅需 1 个 RTT(往返时间)(客户端 → 服务器 → 客户端)即可完成,而 TLS 1.2 需 2 个 RTT,核心优化是"将密钥交换和认证并行处理"。

完整流程分为 4 个关键步骤:

  1. 客户端问候(Client Hello):客户端发起连接,提供支持的协议版本、加密套件、随机数等。
  2. 服务器问候 + 证书 + 密钥交换 + 完成(Server Hello + Certificate + Certificate Verify + Finished):服务器回应,认证身份,协商密钥。
  3. 客户端验证 + 完成(Client Finished):客户端验证服务器身份,确认密钥,握手完成。
  4. 应用数据传输:用协商的对称密钥加密 HTTP 数据。

步骤拆解(带数据包细节)

1. 第一步:客户端发送 Client Hello(客户端 → 服务器)

客户端发起连接时,发送第一个数据包,核心目的是"告知服务器自己的能力,提供密钥交换的初始材料"。

数据包包含核心字段

  • TLS 版本:客户端支持的最高版本(如 TLS 1.3)。
  • 随机数(Client Random):32 字节随机数(由客户端生成,用于后续密钥计算,非对称加密无法破解)。
  • 加密套件列表(Cipher Suites) :客户端支持的加密套件(按优先级排序),格式为"密钥交换算法-对称加密算法-哈希算法",例如:
    • TLS_AES_256_GCM_SHA384:ECDH 密钥交换 + AES-256-GCM 对称加密 + SHA-384 哈希。
    • TLS_CHACHA20_POLY1305_SHA256:适合低功耗设备(如手机)。
  • 扩展字段(Extensions)
    • supported_groups:支持的椭圆曲线(如 secp256r1、x25519,用于 ECDH 密钥交换)。
    • key_share:客户端的 ECDH 公钥(客户端生成椭圆曲线密钥对,发送公钥给服务器,私钥自己保留)。
    • signature_algorithms:支持的数字签名算法(如 ECDSA-SHA384,用于验证服务器证书签名)。
    • server_name:SNI(服务器名称指示),告知服务器要访问的域名(如 www.baidu.com),支持一台服务器部署多个 HTTPS 站点(共享 IP)。

TLS 1.2 差异

  • TLS 1.2 无 key_share 扩展,客户端仅发送支持的密钥交换算法(如 RSA、ECDH),不携带公钥,需后续额外步骤交换密钥(导致多 1 个 RTT)。
  • TLS 1.2 加密套件包含密钥交换算法(如 TLS_RSA_WITH_AES_256_CBC_SHA256),而 TLS 1.3 密钥交换算法统一为 ECDH(简化设计)。
2. 第二步:服务器发送 Server Hello + 证书 + 密钥交换 + 完成(服务器 → 客户端)

服务器收到 Client Hello 后,综合自身配置(如支持的 TLS 版本、加密套件)回应,核心目的是"确认通信参数、认证自己的身份、完成密钥交换"。这一步是 TLS 握手的核心,包含 4 个关键子消息(打包在一个 TCP 数据包中):

(1)Server Hello(确认通信参数)
  • 选择双方都支持的 最高 TLS 版本(如 TLS 1.3)。
  • 选择双方都支持的 加密套件 (如 TLS_AES_256_GCM_SHA384)。
  • 服务器随机数(Server Random):32 字节随机数(服务器生成,与 Client Random 共同用于密钥计算)。
  • 扩展字段:确认 key_share(服务器的 ECDH 公钥)、server_name 等。
(2)Certificate(发送数字证书,认证身份)

服务器发送自己的 X.509 数字证书(可能是证书链,包含服务器证书、中间 CA 证书),核心目的是"证明自己是域名的合法所有者,同时提供公钥"。

证书的详细结构见下文"三、数字证书深度解析",此处重点说明:客户端通过验证证书的有效性,确认"服务器的公钥是可信的"(避免中间人替换公钥)。

(3)Certificate Verify(数字签名,验证证书私钥所有权)

服务器用自己证书对应的 私钥,对"握手过程中的关键数据(如 Client Random、Server Random、密钥交换材料)"进行数字签名,发送给客户端。

客户端收到后,用证书中的 公钥 验证该签名:

  • 若验证通过:证明服务器确实拥有证书对应的私钥(即"服务器是证书的合法持有者",排除中间人伪造证书的可能)。
  • 若验证失败:握手终止,通信中断。

TLS 1.2 差异:TLS 1.2 中,若密钥交换算法为 RSA(即"RSA 密钥交换"),则服务器会用私钥加密"预主密钥(Pre-Master Secret)",无需 Certificate Verify 消息;而 TLS 1.3 强制使用 ECDH 密钥交换,必须通过 Certificate Verify 验证私钥所有权。

(4)Finished(验证密钥协商完整性)

服务器用"已协商的对称密钥"加密"握手过程的所有消息摘要",发送给客户端。客户端收到后,用同样的密钥解密,对比摘要是否一致:

  • 一致:说明密钥协商过程未被篡改,密钥是安全的。
  • 不一致:说明握手被中间人篡改,终止通信。
3. 第三步:客户端发送 Client Finished(客户端 → 服务器)

客户端完成以下操作后,发送 Finished 消息,标志握手完成:

  1. 验证服务器证书:检查证书是否过期、是否被吊销、域名是否匹配、证书链是否可信(根 CA 证书在客户端信任列表中)。
  2. 验证 Certificate Verify 签名:用证书公钥验证服务器的数字签名,确认服务器身份合法。
  3. 计算对称密钥 :通过 Client Random、Server Random、ECDH 密钥交换的"共享密钥",结合哈希函数,生成最终的 会话密钥(Session Key) (TLS 1.3 中称为"Traffic Key")。
    • 密钥计算逻辑:Session Key = HKDF(ECDH 共享密钥, Client Random + Server Random, 哈希算法)(HKDF 是密钥派生函数,避免直接使用原始共享密钥)。
  4. 发送 Finished 消息:用会话密钥加密"握手消息摘要",发送给服务器。服务器收到后解密验证,确认客户端已正确获取会话密钥。
4. 第四步:应用数据传输(双向加密)

握手完成后,客户端和服务器均持有相同的会话密钥,后续所有 HTTP 数据(请求行、请求头、请求体,响应行、响应头、响应体)均通过以下方式传输:

  • 加密:用对称加密算法(如 AES-GCM)加密 HTTP 数据。
  • 完整性校验:用哈希函数(如 SHA-256)生成数据摘要,与加密数据一起发送(AES-GCM 是"认证加密算法",内置完整性校验,无需额外步骤)。

TLS 1.2 差异:TLS 1.2 支持非认证加密算法(如 AES-CBC),需额外用 HMAC 进行完整性校验,而 TLS 1.3 仅支持认证加密算法(更安全)。

会话复用流程(优化延迟)

为避免每次连接都进行完整握手(1 个 RTT 延迟),TLS 1.3 支持 会话票据(Session Ticket) 复用:

  1. 第一次握手完成后,服务器生成一个"会话票据"(包含过期时间、复用的会话密钥等,用服务器的长期密钥加密),发送给客户端。
  2. 客户端下次连接时,在 Client Hello 中携带该会话票据。
  3. 服务器验证票据有效后,直接跳过证书验证、密钥交换步骤,用票据中的会话密钥加密通信,握手仅需 0 个 RTT(即时传输应用数据)。

三、数字证书深度解析(X.509 标准)

数字证书是 TLS 认证的核心,本质是"由权威第三方(CA,Certificate Authority)签名的身份凭证",解决了"公钥信任问题"------客户端如何确认"服务器提供的公钥是真实的,而非中间人伪造的"。

3.1 核心作用

  1. 绑定身份与公钥 :证明"某个域名(如 www.taobao.com)的合法所有者,对应的公钥是 XXXX"。
  2. 提供信任链:通过 CA 的签名,将服务器身份的信任转移到 CA(客户端预装了根 CA 证书,默认信任根 CA)。
  3. 防篡改:证书内容被 CA 签名,中间人无法修改证书中的公钥、域名等信息(修改后签名会失效)。

3.2 X.509 证书结构(ASN.1 编码)

X.509 是数字证书的国际标准,所有 HTTPS 证书均遵循此标准,其核心字段(简化后)如下:

字段名称 作用说明
Version(版本) X.509 v3(目前主流版本,支持扩展字段)
Serial Number(序列号) CA 分配给证书的唯一标识(用于吊销证书)
Signature Algorithm(签名算法) CA 签署证书所用的算法(如 ECDSA-SHA256、RSA-SHA384)
Issuer(签发者) 签发证书的 CA 信息(如"Let's Encrypt Authority X3"),包含 CA 名称、公钥标识
Validity(有效期) 证书的有效时间(Not Before:生效时间;Not After:过期时间)
Subject(主体) 证书所有者信息(HTTPS 场景下,核心是 Common NameSubject Alternative Name(SAN),即域名)
Subject Public Key Info(主体公钥信息) 证书所有者的公钥 + 公钥算法(如 ECDH 公钥 + 椭圆曲线参数)
Extensions(扩展字段) 关键扩展(TLS 必须):
- Subject Alternative Name(SAN) 支持多个域名(如 www.baidu.combaidu.com),替代老旧的 Common Name
- Key Usage(密钥用途) 限制公钥用途(如"仅用于 TLS 服务器认证")
- Authority Information Access(AIA) 指向 CA 的证书吊销列表(CRL)或在线证书状态协议(OCSP)地址,用于验证证书是否被吊销
Signature(签名) CA 用自己的私钥,对"证书除签名外的所有字段"计算的数字签名(验证证书完整性和合法性)

3.3 证书链(信任链)

服务器发送的证书通常是"证书链"(而非单张证书),原因是:客户端仅预装"根 CA 证书"(如 VeriSign、Let's Encrypt 根 CA),而服务器证书是由"中间 CA"签发的(根 CA 不直接签发服务器证书,避免根私钥泄露)。

证书链结构示例(从服务器到根 CA):

复制代码
服务器证书(www.baidu.com)→ 中间 CA 证书(DigiCert Global CA G2)→ 根 CA 证书(DigiCert Global Root CA)

客户端验证证书链的流程:

  1. 验证服务器证书的签名:用中间 CA 证书的公钥解密服务器证书的签名,对比证书内容的摘要,确认服务器证书未被篡改。
  2. 验证中间 CA 证书的签名:用根 CA 证书的公钥解密中间 CA 证书的签名,确认中间 CA 证书合法。
  3. 验证根 CA 证书:根 CA 证书是"自签名证书"(用自己的私钥签名),且已预装在客户端(操作系统或浏览器信任列表中),直接信任。

3.4 证书吊销机制(避免过期/泄露证书被滥用)

若证书的私钥泄露、域名变更,CA 会将该证书"吊销",客户端需验证证书是否已吊销,主要通过两种方式:

  1. CRL(Certificate Revocation List,证书吊销列表) :CA 定期发布包含所有吊销证书序列号的列表,客户端下载后查询服务器证书序列号是否在列表中。
    • 缺点:列表体积大,更新不及时。
  2. OCSP(Online Certificate Status Protocol,在线证书状态协议) :客户端向 CA 的 OCSP 服务器发送证书序列号,实时查询证书状态。
    • 优化:TLS 1.3 支持 OCSP Stapling(OCSP 装订),服务器提前向 OCSP 服务器查询自己的证书状态,将结果绑定在证书中发送给客户端,避免客户端额外请求 OCSP 服务器(减少延迟)。

四、数字签名深度解析(原理 + 验证流程)

数字签名是"非对称加密的逆向应用",核心作用是 "验证数据来源的合法性 + 数据完整性",在 TLS 中用于两个关键场景:

  1. CA 对数字证书的签名(验证证书合法)。
  2. 服务器对 Certificate Verify 消息的签名(验证服务器拥有证书私钥)。

4.1 核心原理

数字签名基于"私钥签名,公钥验证"的逻辑,结合哈希函数(避免直接对大数据加密,提高效率),流程如下:

签名流程(签名者:CA 或服务器)
  1. 生成数据摘要:对需要签名的原始数据(如证书内容、握手消息),用哈希函数(如 SHA-256)计算摘要(固定长度,不可逆,数据微小变化会导致摘要完全不同)。
  2. 私钥加密摘要:用签名者的私钥(CA 的私钥、服务器的私钥)对摘要进行加密,生成"数字签名"。
验证流程(验证者:客户端)
  1. 生成数据摘要:对收到的原始数据(如证书、握手消息),用相同的哈希函数计算摘要。
  2. 公钥解密签名:用签名者的公钥(CA 证书的公钥、服务器证书的公钥)对收到的数字签名进行解密,得到"原始摘要"。
  3. 对比摘要 :将自己计算的摘要与解密得到的原始摘要对比:
    • 一致:数据未被篡改,且确实是签名者发送的(只有签名者的私钥能生成该签名)。
    • 不一致:数据被篡改,或签名者身份伪造(中间人用自己的私钥签名)。

4.2 数学过程(以 RSA 签名为例)

RSA 签名是最常用的签名算法,基于大整数分解的数学难题,步骤如下:

前提(RSA 密钥对)
  • 私钥:(d, n)(d 是私有指数,n 是大整数,由两个大质数相乘得到)。
  • 公钥:(e, n)(e 是公开指数,通常取 65537,n 与私钥相同)。
签名流程(服务器/CA 侧)
  1. 对原始数据 M 计算哈希摘要:H = SHA-256(M)(H 是 32 字节固定长度)。
  2. 对摘要 H 进行"填充"(如 PKCS#1 v1.5 或 PSS 填充,避免安全漏洞),得到 H'。
  3. 用私钥加密 H':Signature = H'^d mod n(RSA 加密本质是模幂运算)。
验证流程(客户端侧)
  1. 对收到的原始数据 M 计算哈希摘要:H = SHA-256(M)
  2. 用公钥解密签名:H' = Signature^e mod n
  3. 对 H' 进行"去填充",得到 H_verify。
  4. 对比 H 与 H_verify:一致则验证通过。

4.3 椭圆曲线签名(ECDSA,TLS 1.3 推荐)

ECDSA(Elliptic Curve Digital Signature Algorithm)是基于椭圆曲线数学的签名算法,相比 RSA 具有以下优势:

  • 密钥长度短(256 位 ECDSA 安全性 ≈ 2048 位 RSA),传输和计算效率更高。
  • 签名体积小(64 字节 vs RSA 256 字节),减少 TLS 握手数据包大小。

ECDSA 签名流程(简化):

  1. 签名者生成临时椭圆曲线密钥对(k, Q)。
  2. 对原始数据 M 计算哈希摘要 H = SHA-256(M)。
  3. 基于椭圆曲线运算生成签名(r, s):r = x 坐标 mod n(x 是 Q 的 x 坐标),s = (H + r*d)/k mod n(d 是签名者私钥)。
  4. 验证者用签名者公钥(椭圆曲线上的点)、H、(r, s) 进行椭圆曲线运算,验证是否满足 r = x' mod n(x' 是运算结果的 x 坐标)。

4.4 数字签名 vs 加密(核心区别)

维度 数字签名 加密
核心目的 认证身份 + 防篡改 机密性(隐藏数据)
密钥使用 私钥签名,公钥验证 公钥加密,私钥解密(非对称);同一密钥(对称)
数据流向 原始数据公开,签名附加在数据后 原始数据隐藏,加密后的数据传输
TLS 中的应用 证书签名、Certificate Verify 消息 密钥交换(RSA 密钥交换)、数据传输(对称加密)

五、TLS 1.2 与 TLS 1.3 核心差异总结

特性 TLS 1.2 TLS 1.3
握手 RTT 2 个(Client Hello → Server Hello → Client Finished) 1 个(Client Hello → Server 响应 → 应用数据)
密钥交换算法 支持 RSA、ECDH、DHE 等 仅支持 ECDH(强制前向安全)
加密套件 支持非认证加密(如 AES-CBC) 仅支持认证加密(AES-GCM、ChaCha20)
会话复用 支持会话 ID、会话票据 仅支持会话票据(0-RTT 复用)
证书验证 可选(RSA 密钥交换时无需) 强制(Certificate Verify 消息)
安全性 存在降级攻击风险(如 POODLE) 修复所有已知漏洞,禁用不安全算法
握手速度 较慢(多 1 个 RTT) 较快(适合移动网络、低延迟场景)

六、常见问题与安全风险

6.1 中间人攻击(MITM)为何失效?

中间人攻击的核心是"拦截并篡改客户端与服务器的通信",但 TLS 通过以下机制防御:

  1. 服务器证书由 CA 签名,中间人无法伪造 CA 签名(没有 CA 私钥)。
  2. 密钥交换基于 ECDH(前向安全),中间人即使拦截了公钥,也无法计算出共享密钥(椭圆曲线离散对数问题不可解)。
  3. Finished 消息验证握手消息摘要,中间人篡改任何消息都会导致摘要不一致。

6.2 前向安全(Forward Secrecy)

TLS 1.3 强制支持前向安全,核心含义是:"即使服务器的长期私钥泄露,过去的通信数据也不会被破解"。原因是:

  • 每次握手协商的会话密钥是"临时密钥"(基于 ECDH 临时密钥对),与服务器长期私钥无关。
  • 长期私钥仅用于签名(认证身份),不参与会话密钥计算,泄露后仅影响未来的连接认证,不影响历史数据。

6.3 常见安全漏洞(已修复)

  • Heartbleed(心脏出血):OpenSSL 库的漏洞,攻击者可通过 TLS 心跳包读取服务器内存中的私钥、会话密钥等敏感信息(修复方式:升级 OpenSSL 版本)。
  • POODLE(贵宾犬):利用 TLS 1.0 降级攻击,破解 AES-CBC 加密的会话密钥(修复方式:禁用 TLS 1.0/1.1,使用 TLS 1.2+)。
  • Logjam:破解弱 Diffie-Hellman 密钥交换(修复方式:使用 2048 位以上 DH 密钥,或改用 ECDH)。

七、总结

HTTPS 的安全核心是 TLS 协议,其本质是"通过密钥交换建立安全的对称加密通道,通过数字证书和数字签名保障身份认证"。关键流程可简化为:

  1. 客户端与服务器通过 ECDH 安全协商会话密钥(1 个 RTT)。
  2. 服务器通过数字证书证明身份(CA 签名保障证书可信)。
  3. 服务器通过数字签名证明自己拥有证书私钥(避免中间人伪造)。
  4. 后续应用数据用会话密钥加密传输(高效、安全)。

数字证书解决了"公钥信任问题",数字签名解决了"身份认证和防篡改问题",两者结合构成了 HTTPS 安全的基石。TLS 1.3 作为最新版本,通过简化流程、强化安全算法,成为目前最推荐的 TLS 版本,也是未来 HTTPS 的主流标准。

相关推荐
Tandy12356_1 小时前
手写TCP/IP协议栈——环境配置
服务器·网络·网络协议·tcp/ip
坐吃山猪1 小时前
Electron03-桌面文件夹
开发语言·javascript·ecmascript
我命由我123451 小时前
微信小程序 - 内容弹出框实现(Vant Weapp 实现、原生实现)
开发语言·前端·javascript·微信小程序·小程序·前端框架·js
豐儀麟阁贵1 小时前
8.6运行时异常
java·开发语言
clear sky .1 小时前
TCP,UDP使用socket编程流程
网络协议·tcp/ip·udp
minji...1 小时前
linux 进程控制(一) (fork进程创建,exit进程终止)
linux·运维·服务器·c++·git·算法
埃伊蟹黄面1 小时前
双指针算法
数据结构·c++·算法
Elias不吃糖1 小时前
Leetcode-10.正则表达式匹配(暴力 或 记忆暴力)
数据结构·c++·算法·leetcode·深度优先
小年糕是糕手1 小时前
【C++】类和对象(四) -- 取地址运算符重载、构造函数plus
c语言·开发语言·数据结构·c++·算法·leetcode·蓝桥杯