大家知道 TCP 建立连接需要 3 次握手,这需要 1.5-RTT,如果再加上 TLS 的握手时间,总共需要 3-RTT,耗时将近 200-300 ms。随着互联网的高速发展,用户对于性能体验要求越来越高,TCP 连接握手带来的长时延显然是不可接受的。QUIC 因此提出一个新的建立连接机制,把传输和加密握手合并成一个,以最小化延迟(1-RTT)建立连接。后续的连接(repeat connections)还可以通过上一次连接时缓存的信息(TLS 1.3 Diffie-Hellman 公钥、传输参数、NEW_TOKEN
帧生成的令牌,等)直接在一个经过认证且加密的通道传输数据(0-RTT),这极大减小了建立连接的时延。

下面我们将基于IETF QUIC 协议草案详细了解下 QUIC 是如何做到能快速建立连接(1-RTT/0-RTT)又能保证安全性。
QUIC 加密握手提供以下属性:
- 认证密钥交换,其中
- 服务端总是经过身份验证
- 客户端可以选择性进行身份验证
- 每个连接都会产生不同并且不相关的密钥
- 密钥材料(keying material)可用于 0-RTT 和 1-RTT 数据包的保护
- 两个端点(both endpoints)传输参数的认证值,以及服务端传输参数的保密保护
- 应用协议的认证协商(TLS 使用 ALPN)
下面显示了一个简化的握手以及相关数据包和帧的交换过程。用 “*” 表示在握手过程中可以进行应用数据交换。一旦握手完成,端点就可以交换应用数据。
Client Server
Initial (CRYPTO)
0-RTT (*) ---------->
Initial (CRYPTO)
Handshake (CRYPTO)
<---------- 1-RTT (*)
Handshake (CRYPTO)
1-RTT (*) ---------->
<---------- 1-RTT (HANDSHAKE_DONE,*)
1-RTT (*) <=========> 1-RTT (*)
注意:
CRYPTO
帧可以在不同的数据包编号空间(packet number spaces)中发送。CRYPTO
帧使用偏移量(offsets)来确保加密握手数据的有序传递的在每个包编号空间(packet number spaces)都是从零开始。- 端点需要显式地协商应用协议(TLS 使用 ALPN)。这避免了对所使用的协议存在分歧的情况。
在QUIC中,数据包编号分为3个空间:
- 初始(Initial)空间:所有初始包都在这个空间中。
- 握手(Handshake)空间:所有握手包都在此空间中。
- 应用数据(Application data)空间:所有 0-RTT 和 1-RTT 加密的数据包都在这个空间中。