HTTP/3:
Hypertext Transfer Protocol Version 3
中文:
超文本传输协议第三版。
HTTP/3 是 HTTP 协议的第三个主要版本。
HTTP/3 最大的变化是:
不再使用 TCP 作为底层传输协议,而是使用基于 UDP 实现的 QUIC 协议。
传统 HTTP/1.1、HTTP/2:
HTTP/1.1 或 HTTP/2
│
▼
TLS ← HTTPS 使用
│
▼
TCP
│
▼
IP
HTTP/3:
HTTP/3
│
▼
QUIC
┌────┴────┐
│ TLS 1.3 │
│可靠传输 │
│多路复用 │
│拥塞控制 │
└────┬────┘
│
▼
UDP
│
▼
IP
注意:
TLS 1.3 并不是简单地放在 QUIC 上面的独立一层。
QUIC 将 TLS 1.3 握手机制集成进自己的连接建立过程。
因此:
HTTP/3 使用 QUIC 实现可靠传输,并通过集成的 TLS 1.3 机制建立加密连接。
| 特性 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 底层传输 | TCP | TCP | QUIC/UDP |
| 可靠传输 | TCP | TCP | QUIC |
| 多路复用 | 不支持 HTTP/2 式多路复用 | 支持 | 支持 |
| 传输层队头阻塞 | 存在 | 存在 | 不同流之间避免 |
| HTTPS 加密 | TLS | TLS | QUIC 集成 TLS 1.3 |
| TCP 三次握手 | 需要 | 需要 | 不需要 |
| 首次安全连接 | TCP + TLS | TCP + TLS | QUIC/TLS 1.3 |
| 连接迁移 | 不原生支持 | 不原生支持 | 支持 |
| 典型端口 | TCP 80/443 | TCP 443 | UDP 443 |
这里需要区分:
HTTP/2 虽然支持多个 HTTP 请求并发传输,但底层 TCP 仍然是单一有序字节流。
如果 TCP 某个数据段丢失:
后续已经到达的数据仍可能等待缺失数据重传。
HTTP/3 使用 QUIC Stream:
不同 Stream 可以独立处理数据。
一个 Stream 发生丢包,不会因为该 Stream 缺失数据而直接阻塞其他 Stream 的有序交付。
但丢包仍可能影响整个连接的拥塞控制。
QUIC:
一种基于 UDP 的安全、多路复用传输协议。
QUIC 主要提供:
QUIC
│
├── Connection Establishment
│ 连接建立
│
├── TLS 1.3 Integration
│ 加密握手
│
├── Reliable Transmission
│ 可靠传输
│
├── Packet Number
│ 数据包编号
│
├── Acknowledgment
│ 数据确认
│
├── Loss Recovery
│ 丢包恢复
│
├── Congestion Control
│ 拥塞控制
│
├── Stream Multiplexing
│ 多路复用
│
└── Connection Migration
连接迁移
UDP 本身不保证:
但是 QUIC 在 UDP 之上实现了相应机制。
所以:
HTTP/3 使用 UDP,不代表 HTTP/3 是不可靠的。
真正提供可靠传输的是 QUIC。
主要原因有三个。
传统 HTTPS(HTTP/2 + TLS 1.3)首次连接:
Client Server
│ │
│ SYN │
│───────────────────────────>│
│ │
│ SYN + ACK │
│<───────────────────────────│
│ │
│ ACK + TLS ClientHello │
│───────────────────────────>│
│ │
│ TLS ServerHello 等 │
│<───────────────────────────│
│ │
│ TLS Finished │
│───────────────────────────>│
│ │
│ HTTP Request │
│───────────────────────────>│
通常需要:
TCP 握手:1 RTT
TLS 1.3 握手:1 RTT
总计:约 2 RTT
这里的 2 RTT 指客户端能够发送安全 HTTP 请求之前的典型握手延迟,不包含 DNS、HTTP 响应传输等时间。
HTTP/3:
QUIC + TLS 1.3
首次连接:
约 1 RTT
因为 QUIC 的传输参数协商和 TLS 握手可以一起进行。
TCP:
TCP Byte Stream
Packet 1 收到
Packet 2 丢失
Packet 3 收到
Packet 4 收到
TCP 必须等待 Packet 2 对应的数据恢复,才能向应用层连续交付后面的字节。
QUIC:
QUIC Connection
│
├── Stream 0
│ └── 丢包
│
├── Stream 4
│ └── 正常传输
│
└── Stream 8
└── 正常传输
不同 Stream 的有序交付相互独立。
TCP 连接通常依赖四元组:
Source IP
Source Port
Destination IP
Destination Port
如果客户端从 Wi-Fi 切换到移动网络:
源 IP 可能变化。
原 TCP 连接通常无法直接继续使用。
QUIC 使用 Connection ID:
即使 IP 地址发生变化,也可能保持原有逻辑连接。
答案:
不需要。
因为 HTTP/3 不使用 TCP。
HTTP/3 通过 QUIC 建立连接。
但是:
不需要 TCP 三次握手,不等于不需要握手。
QUIC 仍然需要:
1. 建立传输连接状态
2. 协商 QUIC 参数
3. 执行 TLS 1.3 握手
4. 验证服务器身份
5. 协商加密密钥
6. 协商应用协议 HTTP/3
因此:
HTTP/3 的连接建立,本质上是:
QUIC Handshake
+
TLS 1.3 Handshake
两者紧密结合完成。
RTT:
Round Trip Time
中文:
往返时间。
表示:
数据从客户端发送到服务器,再从服务器返回客户端所经历的时间。
例如:
Client Server
│ │
│ Request │
│───────────────────────────>│
│ │
│ Response │
│<───────────────────────────│
│ │
1 RTT
假设:
RTT = 100ms
那么:
TCP 三次握手
约 100ms
传统 TCP + TLS 1.3:
TCP 连接:100ms
TLS 握手:100ms
总计:约 200ms
HTTP/3 首次连接:
QUIC + TLS 1.3
约 100ms
注意:
这是理想化的握手时间对比。
实际时间还受到网络拥塞、丢包、服务器处理时间、证书验证和协议回退等因素影响。
理解 HTTP/3 连接建立之前,需要先理解几个字段。
Connection ID
Packet Number
ACK Frame
CRYPTO Frame
STREAM Frame
Transport Parameters
这些字段的作用类似于 TCP 中:
Source Port
Destination Port
SEQ
ACK
Flags
但是 QUIC 的实现方式与 TCP 不同。
Connection ID:
连接标识符。
简称:
CID。
QUIC 使用 Connection ID 帮助识别和路由连接。
例如:
Client
IP = 192.168.1.10
Port = 50000
│
│ QUIC
│
▼
Server
IP = 192.168.1.20
Port = 443
连接建立时,双方可以使用:
Source Connection ID
Destination Connection ID
即:
SCID
DCID
注意:
QUIC 的连接标识不只是简单的一个全局固定 CID。
双方可以各自提供 Connection ID,并且在连接生命周期中更新。
例如:
Client → Server
Destination CID = Server CID
表示:
当前数据包发往服务器所标识的连接。
Connection ID 的重要用途:
连接路由
连接迁移
减少对 IP/Port 四元组的依赖
Packet Number:
数据包编号。
简称:
PN。
TCP 使用:
Sequence Number
标识字节流中的位置。
QUIC 使用:
Packet Number
标识发送的数据包。
例如:
Packet Number = 0
Packet Number = 1
Packet Number = 2
Packet Number = 3
但是需要特别注意:
QUIC 的 Packet Number 与 TCP 的 SEQ 不一样。
TCP:
SEQ
标识字节位置
QUIC:
Packet Number
标识 QUIC 数据包
QUIC 还使用 Stream Offset 标识流中数据的位置。
例如:
Stream ID = 0
Offset = 0
Length = 100
表示:
当前数据属于 Stream 0,覆盖偏移量 0~99 的字节。
另外:
QUIC 有三个 Packet Number Space:
Initial
Handshake
Application Data
其中 0-RTT 和 1-RTT 共用 Application Data Packet Number Space。
ACK:
Acknowledgment
确认。
QUIC 通过 ACK Frame 确认接收到的数据包。
例如:
Client → Server
Packet Number = 10
服务器收到以后:
Server → Client
ACK Frame
Acknowledged Packet = 10
但是:
QUIC 的 ACK 不等于 TCP 的 ACK Number。
TCP:
ACK Number = 501
通常表示:
期望接收下一个连续字节序号 501。
QUIC:
ACK Frame
可以描述:
已收到 Packet 1
已收到 Packet 2
未收到 Packet 3
已收到 Packet 4
已收到 Packet 5
通过 ACK Range 表达已收到的数据包区间。
所以:
QUIC 的 ACK 确认数据包,而 TCP 的累计 ACK 主要确认连续字节位置。
CRYPTO Frame:
用于传输 TLS 握手消息。
例如:
ClientHello
ServerHello
EncryptedExtensions
Certificate
CertificateVerify
Finished
QUIC 并不是将普通 TLS Record 直接封装在 UDP 中。
而是把 TLS 握手消息放进:
QUIC CRYPTO Frame
例如:
QUIC Initial Packet
│
▼
CRYPTO Frame
│
▼
TLS ClientHello
CRYPTO Frame 具有自己的 Offset。
这样可以在发生丢包时重新传输尚未确认的握手数据。
QUIC v1 连接建立过程中主要使用:
| Packet | 作用 |
|---|---|
| Initial | 开始连接,携带初始 TLS 握手消息 |
| Handshake | 传输后续 TLS 握手消息 |
| 0-RTT | 恢复连接时发送早期应用数据 |
| 1-RTT | 使用应用数据密钥传输数据 |
| Retry | 服务器要求客户端验证地址 |
其中:
Initial
Handshake
0-RTT
使用长包头格式。
1-RTT
通常使用短包头格式。
注意:
这些是 QUIC Packet 类型。
不是 TCP 的:
SYN
ACK
FIN
假设用户访问:
https://www.example.com
客户端:
192.168.1.10
服务器:
192.168.1.20
服务器 HTTP/3 端口:
UDP 443
首先:
浏览器需要知道服务器支持 HTTP/3。
常见方式:
DNS HTTPS/SVCB 记录
或者
Alt-Svc 响应头
或者
之前缓存的 HTTP/3 服务信息
例如:
Alt-Svc: h3=":443"; ma=86400
表示服务器声明存在 HTTP/3 替代服务。
然后客户端尝试 QUIC 连接。
完整的典型握手:
Client Server
│ │
│ Initial │
│ CRYPTO: ClientHello │
│────────────────────────────────────>│
│ │
│ Initial │
│ ServerHello │
│<────────────────────────────────────│
│ │
│ Handshake │
│ EncryptedExt │
│ Certificate │
│ CertVerify │
│ Finished │
│<────────────────────────────────────│
│ │
│ 验证证书、计算密钥 │
│ │
│ Handshake │
│ Finished │
│────────────────────────────────────>│
│ │
│ 1-RTT │
│ HTTP/3 Request │
│────────────────────────────────────>│
│ │
│ 1-RTT │
│ HANDSHAKE_DONE│
│ HTTP Response │
│<────────────────────────────────────│
│ │
│ Secure QUIC Connection │
说明:
图中展示的是典型的逻辑消息顺序。
实际网络中:
客户端希望连接服务器。
发送:
QUIC Initial Packet
其中包含:
QUIC Version
Destination Connection ID
Source Connection ID
Packet Number
CRYPTO Frame
CRYPTO Frame 中:
TLS ClientHello
ClientHello 主要包含:
Supported TLS Versions
Cipher Suites
Key Share
Supported Groups
Server Name Indication
ALPN
TLS Extensions
例如:
ClientHello
TLS Version = TLS 1.3
SNI = www.example.com
ALPN = h3
KeyShare = Client Public Key
这里:
SNI:
告诉服务器客户端希望访问哪个域名。
ALPN:
Application-Layer Protocol Negotiation。
用于协商应用层协议。
h3
表示 HTTP/3。
KeyShare:
用于 TLS 1.3 密钥协商。
需要注意:
ClientHello 中的 KeyShare 不是最终的对称加密密钥。
而是密钥交换所需要的公开参数。
服务器收到 Initial Packet。
首先解析 QUIC Initial。
然后读取:
TLS ClientHello
服务器选择:
TLS 版本
密码套件
密钥交换参数
发送:
ServerHello
例如:
TLS Version = TLS 1.3
Cipher Suite = TLS_AES_128_GCM_SHA256
KeyShare = Server Public Key
客户端和服务器根据双方的密钥交换参数:
计算共享秘密。
典型情况下使用:
ECDHE
即:
Elliptic Curve Diffie-Hellman Ephemeral。
中文:
临时椭圆曲线迪菲-赫尔曼密钥交换。
它的重要特点:
双方可以通过各自的私钥与对方公钥计算相同的共享秘密。
但不需要通过网络直接发送共享秘密。
例如:
Client Private Key
+
Server Public Key
│
▼
Shared Secret
服务器:
Server Private Key
+
Client Public Key
│
▼
Shared Secret
最终:
Client Shared Secret
=
Server Shared Secret
然后通过 TLS 1.3 的密钥派生过程:
生成握手阶段的加密密钥。
服务器发送:
EncryptedExtensions
Certificate
CertificateVerify
Finished
这些消息通常位于:
QUIC Handshake Packet
中。
包含服务器确认的 TLS 扩展信息。
例如:
ALPN = h3
说明:
服务器选择使用 HTTP/3。
注意:
ClientHello 中提供 h3,不代表服务器一定接受。
只有协商成功,才能按照 HTTP/3 通信。
服务器发送证书链。
证书中包含:
服务器身份信息
服务器公钥
证书有效期
证书签名
域名相关信息
证书的主要作用:
帮助客户端验证服务器身份。
服务器使用与证书对应的私钥:
对握手上下文进行数字签名。
客户端通过证书中的公钥:
验证签名。
作用:
证明服务器拥有与证书公钥对应的私钥。
Finished 用于验证握手消息的完整性,并证明对方拥有相应的握手密钥。
它不是简单的:
握手完成通知
而是 TLS 握手安全验证的重要组成部分。
客户端收到:
Certificate
以后,需要进行证书验证。
主要包括:
1. 检查证书链
2. 检查证书签名
3. 检查证书有效期
4. 检查证书是否适用于目标域名
5. 检查证书信任关系
6. 按客户端策略进行撤销状态等检查
例如:
访问:
https://www.example.com
服务器证书必须适用于:
www.example.com
如果证书不可信:
浏览器通常会提示:
Certificate Error
或阻止连接。
注意:
HTTPS 加密连接安全,不仅需要加密,还需要验证服务器身份。
否则可能遭受中间人攻击。
客户端完成:
服务器证书验证
服务器签名验证
TLS Finished 验证
密钥派生
然后发送:
Client Finished
通常放在:
QUIC Handshake Packet
中。
服务器收到以后:
验证客户端的 Finished。
成功后:
服务器可以确认 TLS 握手完成。
客户端在完成服务器认证并具备应用密钥后,通常已经可以发送:
QUIC 1-RTT Packet
因此:
客户端的 Finished 与第一个 HTTP/3 请求可能在同一批次发送。
不必再额外等待一次完整 RTT。
TLS 协商:
ALPN = h3
QUIC 建立安全连接以后:
HTTP/3 需要建立控制流。
发送:
SETTINGS Frame
例如:
HTTP/3 Control Stream
SETTINGS
随后客户端通过 QUIC Stream 发送 HTTP 请求。
例如:
GET / HTTP/3
Host: www.example.com
注意:
上面是便于理解的文本表示。
实际 HTTP/3 不直接以 HTTP/1.1 文本报文格式传输。
HTTP/3 使用:
HEADERS Frame
DATA Frame
请求头使用:
QPACK
压缩。
例如:
QUIC Stream
│
▼
HTTP/3 HEADERS
│
▼
HTTP/3 DATA
服务器返回:
HTTP Status = 200
Response Headers
Response Body
整个过程使用 QUIC 的加密保护。
这是最重要的知识点。
传统 HTTPS:
TCP
│
▼
TCP Three-Way Handshake
│
▼
TLS Handshake
│
▼
HTTPS Application Data
HTTP/3:
UDP
│
▼
QUIC Initial
│
▼
TLS 1.3 Handshake
│
├── Server Authentication
│
├── Key Exchange
│
├── Encryption Keys
│
└── ALPN = h3
│
▼
QUIC 1-RTT
│
▼
HTTP/3 Application Data
因此:
HTTP/3 建立 HTTPS 连接,不是先建立普通 QUIC 连接,再独立进行一次 TLS 握手。
而是:
QUIC 在连接建立过程中直接集成 TLS 1.3 握手,同时完成传输连接参数协商、服务器认证和密钥协商。
1-RTT:
One Round Trip Time。
在 QUIC 中:
通常指首次安全连接建立约需一个网络往返,随后客户端可以发送受 1-RTT 密钥保护的应用数据。
例如:
Client Server
│ │
│ Initial + ClientHello │
│───────────────────────────────>│
│ │
│ ServerHello + TLS Messages │
│<───────────────────────────────│
│ │
│ Finished + HTTP Request │
│───────────────────────────────>│
在客户端收到服务器握手消息以后:
即可完成必要验证并发送加密 HTTP 请求。
所以:
首次连接:
约 1 RTT
这里不代表:
HTTP 响应一定能在 1 RTT 内返回。
因为服务器还需要收到请求、处理请求并返回响应。
0-RTT:
Zero Round Trip Time。
中文:
零往返早期数据。
它的核心作用:
客户端在恢复之前建立过的安全会话时,可以在第一批数据包中直接发送部分应用数据。
例如:
第一次访问:
Client
│
▼
QUIC + TLS 1.3 Handshake
│
▼
HTTPS Communication
│
▼
Session Resumption Information
后续访问:
Client Server
│ │
│ Initial + ClientHello │
│ │
│ 0-RTT Application Data │
│───────────────────────────────>│
│ │
│ TLS Handshake │
│<──────────────────────────────>│
│ │
│ 1-RTT Communication │
│<──────────────────────────────>│
这样:
客户端不必等待服务器的第一次握手响应,就可以尝试发送早期数据。
但是:
0-RTT 有几个重要限制。
客户端需要持有有效的 TLS 会话恢复信息。
例如:
Session Ticket
并从中恢复相关的 PSK 信息。
PSK:
Pre-Shared Key。
预共享密钥。
服务器可能:
Accept 0-RTT
也可能:
Reject 0-RTT
如果拒绝:
客户端需要在正常握手完成后,按协议和应用语义重新处理早期请求。
0-RTT Early Data:
不具备与正常 1-RTT 应用数据相同的抗重放保证。
例如:
POST /transfer
如果请求具有资金转账等副作用:
错误地允许重放,可能造成严重问题。
所以:
0-RTT 通常更适合可安全重放的请求。
例如:
GET /index.html
但也不能简单认为所有 GET 请求都绝对安全。
必须结合服务端业务语义判断。
UDP:
不保证可靠传输。
QUIC:
通过自身机制实现可靠数据流。
例如:
Client Server
│ │
│ Packet Number = 1 │
│───────────────────────────────>│
│ │
│ Packet Number = 2 │
│──────────────X │
│ │
│ Packet Number = 3 │
│───────────────────────────────>│
│ │
│ ACK: Packet 1, Packet 3 │
│<───────────────────────────────│
客户端发现:
Packet 2
可能已经丢失。
于是进行丢包恢复。
注意:
QUIC 不像 TCP 那样简单地重发相同序列号的数据段。
QUIC 的重传通常是:
将丢失的数据重新封装进新的 Packet。
例如:
Original Packet
PN = 2
STREAM Offset = 100
Length = 100
丢失以后:
New Packet
PN = 4
STREAM Offset = 100
Length = 100
所以:
Packet Number 改变
但:
Stream Offset 不变
因为应用数据在 Stream 中的位置没有改变。
这就是 QUIC 可靠传输的重要机制。
HTTP/3 可以在一个 QUIC Connection 中:
同时传输多个 HTTP 请求。
例如:
QUIC Connection
│
├── Stream 0
│ HTTP Request A
│
├── Stream 4
│ HTTP Request B
│
└── Stream 8
HTTP Request C
这里使用客户端发起的双向 Stream ID 举例。
QUIC Stream ID 包含:
发起方信息
单向/双向信息
流编号
不同类型的 Stream 使用不同的编号序列。
如果:
Stream 0
发生丢包:
Stream 4
Stream 8
仍然可以独立交付已收到的连续数据。
这解决了 TCP 层面的跨流队头阻塞问题。
但是:
QUIC 仍然存在:
网络拥塞
带宽限制
连接级流量控制
因此并不代表某个 Stream 丢包对其他 Stream 的性能完全没有影响。
假设客户端使用 Wi-Fi:
Client IP = 192.168.1.10
与服务器建立 QUIC 连接。
随后切换到移动网络:
Client IP = 10.20.30.40
TCP:
源 IP 改变
原 TCP 连接通常无法继续
QUIC:
旧网络:
192.168.1.10:50000
│
▼
QUIC Connection
│
▼
Server:443
切换网络:
新网络:
10.20.30.40:51000
│
▼
QUIC Connection
│
▼
Server:443
QUIC 可以借助:
Connection ID
继续识别连接。
同时:
QUIC 可以执行路径验证。
典型使用:
PATH_CHALLENGE
PATH_RESPONSE
确认新网络路径可用。
例如:
Client Server
│ │
│ New Network Path │
│──────────────────────────────>│
│ │
│ PATH_CHALLENGE │
│<──────────────────────────────│
│ │
│ PATH_RESPONSE │
│──────────────────────────────>│
│ │
│ Path Validated │
需要注意:
连接迁移并非任何情况下都一定成功。
例如:
服务器策略、网络阻断、零长度 CID 或连接状态丢失等,都可能限制迁移。
TCP:
通常使用:
FIN
ACK
完成正常关闭。
QUIC:
不使用 TCP 四次挥手。
QUIC 可以通过:
CONNECTION_CLOSE Frame
关闭连接。
例如:
Client Server
│ │
│ CONNECTION_CLOSE │
│───────────────────────────────>│
│ │
│ │
│ Connection Closing │
QUIC 连接关闭涉及:
Closing State
Draining State
Terminated State
其中:
Closing:
主动关闭方保留有限连接状态,可能对后续收到的数据包再次发送关闭信息。
Draining:
收到关闭信息的一方停止正常发送。
Terminated:
连接资源最终释放。
QUIC 还可以通过:
Idle Timeout
在连接长时间没有活动时结束连接。
此外:
HTTP/3 可以通过:
GOAWAY
表示不再接受新的请求。
但是:
HTTP/3 GOAWAY 不等于 QUIC CONNECTION_CLOSE。
GOAWAY 属于应用层的优雅关闭机制。
CONNECTION_CLOSE 属于连接关闭机制。
不一定。
HTTP/3 的优势主要体现在:
高延迟网络
存在一定丢包的网络
移动网络
网络切换
多请求并发
例如:
移动网络环境:
RTT = 150ms
传统 HTTPS 首次连接:
TCP + TLS 1.3
约 300ms 握手延迟
HTTP/3:
QUIC + TLS 1.3
约 150ms 握手延迟
理想情况下可以减少一次 RTT。
但是:
如果网络质量很好:
RTT = 5ms
那么减少一次 RTT 只节省约:
5ms
而且:
QUIC 运行在 UDP 之上,其用户态实现、加解密、网络设备支持等也可能产生开销。
所以:
HTTP/3 不是在任何网络环境下都绝对快于 HTTP/2。
打开 Chrome 或 Edge。
按:
F12
进入:
Network
右键表头:
启用:
Protocol
查看请求使用的协议。
例如:
h2
表示:
HTTP/2。
h3
表示:
HTTP/3。
注意:
网站支持 HTTP/3,不代表当前请求一定使用 HTTP/3。
如果 curl 编译时支持 HTTP/3:
curl --http3 https://www.example.com -I
也可以尝试:
curl --http3-only https://www.example.com -I
查看 curl 是否支持 HTTP/3:
curl -V
检查 Features 中是否包含:
HTTP3
如果没有:
说明当前 curl 构建可能不支持 HTTP/3。
常见 QUIC 流量:
UDP Port 443
Wireshark 过滤:
quic
或者:
udp.port == 443
可以观察:
Initial
Handshake
0-RTT
1-RTT
Retry
注意:
UDP 443 不一定就是 QUIC。
而且:
QUIC 的握手阶段和应用数据阶段采用不同的密钥保护。
要解密完整的 TLS 握手后续内容及 HTTP/3 请求,通常需要额外的会话密钥日志。
TCP:
Client Server
│ │
│ SYN │
│───────────────────────────────>│
│ │
│ SYN + ACK │
│<───────────────────────────────│
│ │
│ ACK │
│───────────────────────────────>│
│ │
│ ESTABLISHED │
主要完成:
TCP 连接状态建立
初始序列号同步
TCP 参数协商
但是:
TCP 三次握手本身不提供 HTTPS 加密。
HTTP/3:
Client Server
│ │
│ Initial + ClientHello │
│───────────────────────────────>│
│ │
│ ServerHello + TLS Handshake │
│<───────────────────────────────│
│ │
│ Finished + 1-RTT Data │
│───────────────────────────────>│
主要完成:
QUIC 连接建立
TLS 1.3 密钥协商
服务器身份验证
QUIC 传输参数协商
HTTP/3 协议协商
两者最大的区别:
TCP 的传输连接建立和 TLS 安全握手通常是两个先后进行的过程,而 QUIC 将传输连接建立与 TLS 1.3 握手结合起来。
HTTP/3:
HTTP/3
│
▼
QUIC
│
├── UDP Transport
│
├── Connection ID
│
├── Packet Number
│
├── ACK Frame
│
├── Loss Recovery
│
├── Congestion Control
│
├── Stream Multiplexing
│
├── Connection Migration
│
└── TLS 1.3
│
├── ClientHello
│
├── ServerHello
│
├── Certificate
│
├── CertificateVerify
│
├── Finished
│
└── Application Keys
完整访问过程:
用户输入 HTTPS URL
│
▼
DNS 解析
│
▼
发现 HTTP/3 服务
│
▼
发送 QUIC Initial
│
▼
发送 TLS ClientHello
│
▼
接收 ServerHello
│
▼
协商共享秘密
│
▼
验证服务器证书
│
▼
完成 TLS Finished
│
▼
协商 ALPN = h3
│
▼
建立 QUIC 1-RTT 通信
│
▼
交换 HTTP/3 SETTINGS
│
▼
发送 HTTP/3 Request
│
▼
接收 HTTP/3 Response
│
▼
复用连接处理更多请求
│
▼
GOAWAY / CONNECTION_CLOSE
│
▼
连接结束
以上是便于理解的逻辑流程,实际协商步骤可能交错或并行进行。
HTTP/3 使用 QUIC,而不是 TCP。
QUIC 基于 UDP,但自身实现可靠传输。
HTTP/3 不需要 TCP 三次握手。
QUIC 集成 TLS 1.3,建立安全连接。
首次 QUIC 安全握手通常需要约 1 RTT。
0-RTT 可以在恢复会话时提前发送应用数据,但存在重放风险。
QUIC 使用 Packet Number 标识数据包,使用 Stream Offset 标识流中数据位置。
QUIC 使用 Connection ID 支持连接识别和迁移。
HTTP/3 使用多个 QUIC Stream,避免 TCP 层面的跨流队头阻塞。
QUIC 通过 CONNECTION_CLOSE 等机制关闭连接,不使用 TCP 四次挥手。
一句话总结:
HTTP/3 是运行在 QUIC 之上的 HTTP 协议。QUIC 基于 UDP,实现可靠传输、多路复用、拥塞控制和连接迁移,并将 TLS 1.3 握手集成到连接建立过程中,使 HTTPS 首次安全连接通常能够在约 1 RTT 后发送应用数据。
RFC 9000 — QUIC: A UDP-Based Multiplexed and Secure Transport
https://www.rfc-editor.org/rfc/rfc9000
RFC 9001 — Using TLS to Secure QUIC
https://www.rfc-editor.org/rfc/rfc9001
RFC 9002 — QUIC Loss Detection and Congestion Control
https://www.rfc-editor.org/rfc/rfc9002
RFC 9114 — HTTP/3
https://www.rfc-editor.org/rfc/rfc9114
RFC 8446 — The Transport Layer Security (TLS) Protocol Version 1.3
https://www.rfc-editor.org/rfc/rfc8446