Octet

Walk me through a TLS 1.3 handshake. Why is it one round trip instead of two?

Show the answer

Say this first

The client sends a ClientHello with its supported versions, cipher suites, signature algorithms, SNI, ALPN and, the key change, a key share: its ephemeral Diffie-Hellman public key for the group it guesses the server will pick. The server replies with ServerHello and its own key share, and both sides can now compute the handshake keys. Everything after ServerHello is encrypted: EncryptedExtensions, Certificate, CertificateVerify and Finished. The client checks them and sends its Finished, already able to send its request. TLS 1.2 needed a separate round trip to agree on parameters before exchanging keys; TLS 1.3 sends the key share up front.

Go deeper

The messages

Output
Client                                              Server
ClientHello
  + supported_versions, key_share, signature_algorithms,
    server_name (SNI), ALPN, psk_key_exchange_modes   ->
                                                    ServerHello + key_share
                                                    {EncryptedExtensions}  (ALPN result)
                                                    {Certificate}
                                                    {CertificateVerify}    (signature over the transcript)
                                               <-   {Finished}
{Finished}
[Application data: GET /]                          ->

Braces mean encrypted with handshake keys. The server can send data right after its Finished.

Round trips before the first request byte

StackRound trips
TCP + TLS 1.23
TCP + TLS 1.32
QUIC (TLS 1.3 inside)1
TLS 1.3 or QUIC resumption with 0-RTTdata in the first flight

What 1.3 removed

RSA key transport (no forward secrecy), static Diffie-Hellman, CBC and RC4 ciphers, SHA-1 in signatures, compression and renegotiation. The cipher suites are AEAD only, for example TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256.

Things that look odd in captures

  • The version field says TLS 1.2; the real version is in the supported_versions extension. This middlebox compatibility mode also sends a dummy ChangeCipherSpec.
  • If the server does not like the client's key share group it sends a HelloRetryRequest, which costs one more round trip.
  • Hybrid post-quantum key shares such as X25519MLKEM768 make the ClientHello larger than one packet, which has exposed middleboxes that assumed a ClientHello fits in one segment.

Traps

  • Saying the server certificate is visible to observers in TLS 1.3. It is encrypted.
How did you do?Book 8.5 Example SystemsBook 8.3 Key Predistribution