← 返回文章列表

HTTPS 请求全链路复盘:从 AES、ECDHE 到 TLS 1.3

2026年7月6日网络安全
HTTPSTLS密码学AESECDHE

HTTPS 请求全链路复盘:从 AES、ECDHE 到 TLS 1.3

最近重新看量子加密相关资料时,我发现一个很现实的问题:很多更前沿的安全概念,最后还是要落回传统密码学的地基上。

比如我们说“量子安全”“后量子密码”“密钥分发”,听起来很新,但如果连一次普通的 HTTPS 请求里,AES 在哪里用、证书解决什么问题、ECDHE 为什么能在被监听的网络里协商出共享密钥,都没有讲清楚,后面的概念就很容易飘在空中。

所以这篇文章不从算法论文开始,而是讲一个最常见的故事:浏览器访问 https://example.com/index.html 时,从 DNS、TCP、TLS 到 HTTP 请求,完整发生了什么。

1. 先把密码学积木摆清楚

HTTPS 不是一种单独的加密算法,而是一套组合拳。里面至少会用到三类能力:对称加密、非对称身份认证、密钥交换。

先看对称加密。所谓对称,就是加密和解密使用同一个 key。常见算法是 AES。它的优势非常直接:速度快,适合保护大量数据。真正的 HTTP 请求体、响应体,最终通常就是靠对称加密算法在 TLS Record 层一段一段保护起来的。

对称加密的风险不在于“算法不够强”,而在于“key 怎么安全交给对方”。如果客户端和服务器已经有同一个 AES key,后续通信就好办;问题是,第一次见面时怎么在公网里协商出这个 key。

从安全强度上看,AES-128 对传统暴力破解大致提供 128-bit 强度。量子计算里的 Grover 算法可以给无结构搜索带来平方级加速,所以粗略理解下,AES-128 面对理想量子搜索时会下降到约 64-bit 量级。它不是“常量时间破解”,也不是量子计算机一来 AES 就废了;更现实的工程判断是,AES-192、AES-256 提供了更高的安全余量。

再看非对称密码。非对称的核心是公钥和私钥成对出现:公钥可以公开,私钥必须保密。它常见有三种用途:

用途怎么用解决什么问题常见例子
加密 / 解密公钥加密,私钥解密让别人安全地告诉我秘密RSA 加密
签名 / 验签私钥签名,公钥验证向别人证明“确实是我发的,且没被改”RSA-PSS、ECDSA、Ed25519
密钥交换双方交换临时公钥,各自用自己的私钥和对方公钥算出同一个共享秘密在被监听的网络中协商对称加密材料ECDHE

这里最容易混淆的是:证书里的公钥通常不是用来“直接加密所有 HTTP 数据”的。现代 TLS 里,证书更核心的作用是证明服务器身份:浏览器通过证书链确认“这个公钥确实属于这个域名”,服务器再用对应私钥对握手 transcript 做签名,证明自己确实持有私钥。

小结: HTTPS 的底层不是单一算法,而是分工协作:对称加密负责高速保护数据,证书和签名负责身份认证,ECDHE 负责在公网中协商出后续对称加密所需的秘密材料。

2. HTTPS 到底在网络栈的哪一层

最常见的记忆方式是:

HTTP/1.1 或 HTTP/2
TLS
TCP
IP

所以在 HTTP/1.1 和 HTTP/2 的语境下,可以粗略说:

HTTPS = HTTP over TLS over TCP

HTTP 是应用层协议,TCP 是传输层协议。TLS 夹在两者之间,给应用层字节流提供加密、完整性校验和身份认证能力。它并不严格对应 OSI 七层模型里的某一层,更像是应用层和传输层之间的一层安全包装。

到了 HTTP/3,情况会变成:

HTTP/3
QUIC
UDP

QUIC 使用 TLS 1.3 的握手和密钥派生机制,但它不是把完整的 TLS Record Layer 原封不动塞到 UDP 里。可以把它理解为:QUIC 把可靠传输、多路复用、拥塞控制和 TLS 1.3 安全能力揉进了一个基于 UDP 的协议里。

今天做 HTTPS 复习,重点看 TLS 1.2 和 TLS 1.3 就够了。TLS 1.0、TLS 1.1 已经被 RFC 8996 明确弃用,更早的 SSL v2、SSL v3 也早就不应该再进入现代系统设计视野。

小结: 对 HTTP/1.1 和 HTTP/2 来说,HTTPS 可以理解为 HTTP 被 TLS 包起来后跑在 TCP 上;对 HTTP/3 来说,TLS 1.3 的能力被 QUIC 集成进协议本身,不能简单画成“TLS over UDP”。

3. 一次 HTTPS 请求的总流程

先不区分 TLS 1.2 和 TLS 1.3,只看一个大轮廓:

浏览器输入 https://example.com/index.html
DNS 解析域名,拿到 IP
建立传输连接
    - HTTP/1.1 / HTTP/2: TCP 三次握手
    - HTTP/3: QUIC 基于 UDP 建连
TLS 握手
    - 协商协议版本和密码套件
    - 验证服务器证书
    - 完成密钥交换
    - 派生后续加密 HTTP 数据的 traffic keys
浏览器构造 HTTP 请求明文
TLS/QUIC 加密并认证这段应用数据
服务器解密、校验、交给 HTTP Server
服务器生成响应,再加密发回浏览器

这里有两个关键点。

第一,DNS 查询本身不一定受 HTTPS 保护。传统 DNS 是明文的,除非使用 DoH、DoT 或其他加密 DNS 方案。很多人说“访问 HTTPS 网站就是全程加密”,严格说是从 TLS 握手建立保护能力之后,HTTP 应用数据才被加密保护。

第二,TLS 握手并不只是为了“拿到一个 AES key”。它还要协商协议参数,验证服务器身份,确认握手过程没有被中间人篡改。否则攻击者可以把自己夹在浏览器和服务器之间,各自建立连接,偷偷转发和篡改内容。

小结: HTTPS 的主线可以理解为:先找到服务器并建立传输通道,再通过 TLS 握手完成身份认证和密钥协商,最后把 HTTP 明文作为加密后的 Application Data 在网络里传输。

4. TLS 1.2:先握手,再切换到加密通信

TLS 1.2 支持多种历史密码套件。为了贴近现代 HTTPS,这里只讨论常见的 ECDHE 场景。

主流程可以压缩成这样:

DNS
→ TCP 三次握手
→ ClientHello
→ ServerHello + Certificate + ServerKeyExchange + ServerHelloDone
→ 浏览器验证证书链、域名、有效期、用途,并验证 ServerKeyExchange 签名
→ ClientKeyExchange
→ 双方分别计算 ECDHE shared secret / premaster secret
→ premaster_secret + client_random + server_random 派生 master_secret
→ master_secret 派生 client_write_key / server_write_key 等材料
→ ChangeCipherSpec + Finished
→ HTTP 请求/响应作为 TLS Application Data 加密传输

展开看,浏览器先发 ClientHello,里面会带上支持的 TLS 版本、随机数 client_random、密码套件列表、SNI、ALPN、支持的椭圆曲线组、签名算法、会话恢复信息等。

服务器返回 ServerHello,选择最终使用的 TLS 版本和密码套件,并给出 server_random。随后服务器发 Certificate,里面包含证书链。注意,证书里有服务器公钥,没有服务器私钥。

如果使用 ECDHE,服务器还会发 ServerKeyExchange。这里包含服务器临时 ECDHE 公钥,并且服务器会用证书对应的私钥对关键握手参数做签名。浏览器验证这个签名,才能确认这份临时 ECDHE 公钥确实来自证书对应的服务器,而不是中间人塞进来的。

随后浏览器发 ClientKeyExchange,包含客户端临时 ECDHE 公钥。到这里,双方都拥有:

自己的临时 ECDHE 私钥 + 对方的临时 ECDHE 公钥

于是双方可以各自算出同一个 shared secret。这个 shared secret 不会直接拿来当 AES key,而是继续和 client_randomserver_random 一起派生出 master_secret,再从 master_secret 派生出两个方向的写入密钥、IV,以及某些非 AEAD 密码套件下的 MAC key。

最后双方通过 ChangeCipherSpec 切换到新密钥,再发送加密的 FinishedFinished 的意义很大:它证明双方看到的握手 transcript 一致,并且双方确实派生出了同样的密钥。如果中间过程被改过,Finished 校验就过不去。

小结: TLS 1.2 的 ECDHE 握手像一次严谨的交接班:证书先证明服务器身份,ECDHE 协商出共享秘密,密钥派生函数生成后续通信密钥,Finished 再确认整场握手没有被篡改。

5. TLS 1.3:把常用安全姿势变成默认姿势

TLS 1.3 的核心变化不是“名字从 1.2 升到 1.3”,而是把很多历史包袱清理掉了。

TLS 1.3 移除了 static RSA key exchange 和 static DH 这类旧模式,主线变成 ECDHE、PSK、PSK+DHE。常规完整握手下,客户端通常 1-RTT 后就可以发送应用数据,服务器证书也会在 ServerHello 之后被握手密钥保护起来。

主流程可以这样记:

DNS
→ TCP 三次握手
→ ClientHello,带客户端 key_share
→ ServerHello,带服务器 key_share
→ 双方立刻计算 ECDHE shared secret
→ HKDF 派生 handshake traffic secrets / keys
→ EncryptedExtensions + Certificate + CertificateVerify + Finished,加密
→ 浏览器验证证书、CertificateVerify 签名、Finished
→ 客户端 Finished
→ 双方派生 application traffic secrets / keys
→ HTTP 请求/响应作为 TLS Application Data 加密传输

最大的节奏变化在 ClientHello。TLS 1.3 客户端一上来就带 key_share,也就是客户端临时 ECDHE 公钥。服务器在 ServerHello 里返回服务器临时 ECDHE 公钥。这样双方在很早的阶段就能算出 shared secret,并通过 HKDF 派生握手阶段的 traffic secrets。

接下来服务器发出的 EncryptedExtensionsCertificateCertificateVerifyFinished 都已经被握手密钥保护。CertificateVerify 是服务器用证书私钥对握手 transcript 做签名,证明“我确实持有这张证书对应的私钥”;Finished 则证明服务器算出了相同的握手密钥,并且握手 transcript 没被改。

浏览器验证服务器证书链、域名、有效期、用途,再验证 CertificateVerifyFinished。验证通过后,浏览器发送自己的 Finished。随后双方派生 application traffic secrets / keys,用来保护真正的 HTTP 应用数据。

TLS 1.3 还有两个常见扩展点容易误解。

第一,会话恢复票据 NewSessionTicket 不是“复用本连接的 AES key”。它是给后续连接做 resumption 用的材料。

第二,KeyUpdate 可以让长连接切到下一代 traffic key,但这不代表“每个 HTTP 请求都会换一次 key”。现实中,数据加密的粒度仍然主要是 TLS record,密钥更新是连接级别的安全机制。

小结: TLS 1.3 把现代 HTTPS 常用的安全实践收敛成更清晰的主线:尽早交换 ECDHE 公钥,尽早派生握手密钥,尽早加密后续握手消息,再用 application traffic keys 保护 HTTP 数据。

6. HTTP 明文什么时候变成密文

TLS 握手完成后,浏览器才真正开始发送 HTTP 请求。以 HTTP/1.1 为例,浏览器内部构造出的明文可能长这样:

GET /index.html HTTP/1.1
Host: example.com
User-Agent: ...
Accept: ...

这段明文不会直接出现在公网里。它会交给 TLS Record Layer,被切成一个或多个 record,再用当前方向的应用数据密钥加密并认证。

如果用 AEAD 密码套件,可以粗略理解成:

TLSCiphertext = AEAD-Encrypt(
  key        = client application traffic key,
  nonce      = 根据 IV 和 record sequence number 构造,
  plaintext  = HTTP request bytes,
  aad        = record metadata
)

服务器收到的是 TLS Application Data 密文。它用客户端方向的 application traffic key 解密,并校验认证标签。校验失败说明数据可能被篡改,连接应当报错;校验成功后,服务器才把还原出来的 HTTP 明文交给 Web Server 或应用框架处理。

响应方向也一样,只是换成服务器方向的 key:

HTTP response plaintext
→ TLS Record Layer 加密和认证
→ TLS Application Data 密文
→ 浏览器解密和校验
→ 浏览器拿到 HTTP 响应明文

这里的“双向 key”很重要。客户端写数据用客户端方向的 key,服务器写数据用服务器方向的 key。这样即使两边都在同一条连接里通信,密钥材料也不会混用。

小结: TLS 保护的不是“一个 HTTP 请求对象”,而是一段段 record。HTTP 请求和响应在应用层是明文结构,进入 TLS Record Layer 后才变成带完整性保护的密文。

7. TLS 1.2 和 TLS 1.3 的差异总表

把两代协议放在一起,对比会更清楚:

维度TLS 1.2TLS 1.3
典型完整握手 RTT通常 2-RTT 才能让客户端安全发送应用数据通常 1-RTT 后客户端可发送应用数据
证书是否明文传输服务器证书通常明文传输ServerHello 之后的证书消息被握手密钥保护
密钥交换历史上支持 RSA key exchange、DHE、ECDHE 等;现代常见 ECDHE移除 static RSA / static DH,主线是 ECDHE / PSK / PSK+DHE
ChangeCipherSpec正式参与密钥切换仅兼容中间设备,不再是核心握手语义
密钥派生premaster_secret → master_secret → key_blockHKDF 派生 early / handshake / application traffic secrets
后续 HTTP 数据client_write_key / server_write_key 等材料保护用 client/server application traffic keys 保护
是否每个 HTTP 请求换 key通常不是通常不是,但连接可通过 KeyUpdate 更新 traffic key
数据加密粒度TLS record 级别TLS record 级别

再浓缩成两条记忆线。

TLS 1.2:

ClientHello
→ ServerHello + Certificate + ServerKeyExchange
→ ClientKeyExchange
→ premaster_secret / master_secret / key_block
→ ChangeCipherSpec + Finished
→ Application Data

TLS 1.3:

ClientHello(key_share)
→ ServerHello(key_share)
→ handshake traffic keys
→ EncryptedExtensions + Certificate + CertificateVerify + Finished
→ application traffic keys
→ Application Data

还有一个现实边界:TLS 1.3 加密了服务器证书消息,但普通 SNI 仍在 ClientHello 里明文出现。要隐藏 SNI,需要 ECH 这类额外机制。因此,“用了 TLS 1.3”不等于“所有元数据都不可见”。

小结: TLS 1.3 的价值在于更少历史包袱、更快握手、更清晰的密钥派生和更早的握手加密;但 HTTPS 仍然不是魔法罩,哪些内容被保护、哪些元数据仍可见,需要按协议阶段具体分析。

总结

一次 HTTPS 请求背后,其实是一场分工明确的协作。

浏览器先通过 DNS 找到服务器,再建立 TCP 或 QUIC 传输通道。TLS 握手阶段,证书链和签名解决“我连的是不是目标服务器”的问题,ECDHE 解决“如何在公网中协商共享秘密”的问题,HKDF 或 TLS 1.2 的 PRF 再把这些秘密材料派生成真正用于通信的 key。

等握手完成后,HTTP 请求和响应才作为 Application Data 被加密传输。网络上看到的是密文 record,不是 GET /index.html 这样的明文。

理解 HTTPS,关键不是背下每个报文名,而是抓住三条主线:

  1. 身份认证:证书链、域名校验、私钥签名。
  2. 密钥协商:ECDHE 让双方在不安全网络里得到同一个 shared secret。
  3. 数据保护:Record Layer 用双向 traffic keys 对 HTTP 数据做加密和完整性校验。

有了这条主线,再回头看量子加密、后量子密码、QUIC、ECH 或证书体系,就不会觉得它们是散落的名词,而是围绕“身份、密钥、数据保护”这三个问题的不同工程答案。

参考资料

返回博客列表