Cryptography / Protocols

TLS 1.3 Handshake & Network Encryption

Transport Layer Security (TLS) 1.3 is the foundational security protocol of the internet, providing confidentiality, integrity, server authentication, and — for its standard full handshake — Perfect Forward Secrecy over TCP networks. Standardized in RFC 9846 — which obsoletes RFC 8446, the original TLS 1.3 specification, rather than merely amending it — TLS 1.3 streamlines the handshake phase to 1-RTT by combining key exchange with initial parameters and deprecating legacy, insecure ciphers.

TLS 1.3 Handshake Architecture (1-RTT)

Unlike a full TLS 1.2 handshake, which required 2 round-trips (2-RTT) before transmitting encrypted application data — TLS 1.2’s abbreviated (session-resumption) handshake could complete in 1-RTT, so “2-RTT” describes the full handshake specifically, not TLS 1.2 as a whole — TLS 1.3 establishes an encrypted channel in just 1-RTT for its full handshake:

TLS 1.3 certificate-authenticated 1-RTT sequence between a client and server, showing the ClientHello key-establishment share, ServerHello response, encrypted certificate flight, client Finished flight, and application data.

TLS 1.3 certificate-authenticated 1-RTT handshake: ordinary X25519 uses two Diffie-Hellman shares, while X25519MLKEM768 uses an ML-KEM encapsulation key plus X25519 share from the client and an ML-KEM ciphertext plus X25519 share from the server; optional ECH is a separate ClientHello extension

Step-by-Step Handshake Sequence

  1. ClientHello + Key Share: Client sends supported cipher suites, protocol version (TLS 1.3), and an ephemeral key share for its chosen group. That may be a finite-field DH value, an ECDH share such as X25519, or the hybrid X25519MLKEM768 group (RFC 10024 §4.1), whose client-side share concatenates a freshly generated ML-KEM-768 encapsulation key with an X25519 share — not an ML-KEM ciphertext. Optional ECH is a separate extension carrying an encrypted ClientHelloInner; it is not part of key_share.
  2. ServerHello + Key Share: Server selects a cipher suite from the client’s offered list and completes the negotiated group’s key-establishment step: a finite-field or elliptic-curve Diffie-Hellman response for an ordinary DH group, or ML-KEM encapsulation against the client’s encapsulation key for X25519MLKEM768 (RFC 10024 §4.2), producing a ciphertext sent alongside the server’s X25519 share. The server derives the Handshake Secret via HKDF from the resulting shared secret; the client derives the same secret by processing the ordinary DH response or decapsulating the hybrid ciphertext. The Main Secret (RFC 9846 §7.1 — called “Master Secret” in the original RFC 8446 wording) is derived immediately afterward via a further HKDF-Extract step; it does not wait for either side’s Finished message. TLS 1.3 negotiates the AEAD separately, so AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305, and AES-CCM remain independent of the selected key-establishment group.
  3. Encrypted Extensions & Certificate: All subsequent handshake messages are encrypted using the derived handshake key. Server sends its X.509 certificate and CertificateVerify signature, then its own Finished message. At this point the server can already derive its application traffic secret — its Derive-Secret call only needs the transcript through the server’s own Finished, which is why TLS 1.3 permits the server to send 0.5-RTT application data before the client’s flight arrives.
  4. Client Finished: The client verifies the server’s handshake transcript, derives its own handshake MAC, and sends its Finished message (preceded by the client’s Certificate/CertificateVerify only if the server requested client authentication). Once the client’s Finished is added to the transcript, both sides can derive the resumption secret, which specifically requires the transcript through the client’s Finished (unlike the application traffic secrets, which only needed the transcript through the server’s Finished) — this client flight happens before ordinary bidirectional application data, per RFC 9846.

This is the handshake as it runs directly over TCP for HTTP/2 and earlier. HTTP/3 does not reuse the TLS record layer at all — it runs over QUIC (RFC 9000), which uses TLS 1.3 (RFC 9001) only for the handshake and key negotiation, then applies its own QUIC packet protection (built on the negotiated AEAD keys) rather than framing application data inside ordinary TLS records. Describing HTTP/3 traffic as “the TLS record layer over AES-GCM” conflates the two transports.

TLS Protocol Version & Security Status Matrix

Version Handshake Latency Security Status & Cryptographic Changes Recommended Action
SSL 2.0 / SSL 3.0 2-RTT CRITICALLY BROKEN: SSL 3.0 specifically is vulnerable to the POODLE CBC-padding oracle; SSL 2.0 specifically is vulnerable to DROWN (a cross-protocol RSA padding-oracle attack) — the two flaws don’t both apply to both versions, but both versions share weak, non-AEAD MAC constructions. PROHIBITED: Must be disabled across all servers.
TLS 1.0 / TLS 1.1 2-RTT DEPRECATED (RFC 8996): Lacks modern AEAD ciphers; TLS 1.0 specifically is vulnerable to the BEAST CBC-chaining attack, and CBC-mode suites in either version are susceptible to Lucky13-style timing attacks — see RFC 8996 for the complete deprecation rationale. PROHIBITED: Disable per PCI-DSS and NIST SP 800-52 Rev. 2.
TLS 1.2 2-RTT (full handshake; abbreviated/resumption handshake can be 1-RTT) LEGACY APPROVED: Secure when restricted to AEAD cipher suites with ephemeral key exchange — ECDHE + AES-GCM (RFC 5289) or ECDHE + ChaCha20-Poly1305 (RFC 7905) are both acceptable; avoid static RSA key exchange and CBC-mode suites. MAINTAIN FOR COMPATIBILITY: Phase out in favor of TLS 1.3.
TLS 1.3 1-RTT (certificate-authenticated full handshake without a HelloRetryRequest; add a round trip if HRR occurs) RECOMMENDED STANDARD: Mandatory AEAD; certificate-authenticated full handshakes use ephemeral finite-field DH, ECDHE, or a standardized hybrid ECDHE+ML-KEM group. PSK-only use without psk_dhe_ke — for either resumption or an externally established PSK — remains permitted but forgoes forward secrecy for that connection. Static RSA key transport is absent (RFC 9846, which obsoletes the original RFC 8446). DEFAULT FOR NEW DEPLOYMENTS: Use TLS 1.3 by default; retain a restricted TLS 1.2 profile (AEAD-only, ECDHE-only, as described above) only where client compatibility genuinely requires it, and phase that out over time.

Advanced TLS 1.3 Features & Security Trade-offs

1. 0-RTT Early Data & Replay Attack Vulnerability

TLS 1.3 allows returning clients to resume sessions and send data in the very first packet (0-RTT). However, because 0-RTT data is transmitted before server handshake completion, an attacker can capture and replay 0-RTT packets.

0-RTT Security Guidance
0-RTT Early Data Replay Protection

Per RFC 9846 §2.3, 0-RTT data carries no non-replay guarantee, so what's actually safe to send over it has to be decided per application, not inferred from an HTTP method's nominal semantics. HTTP idempotence (a request whose end state is the same no matter how many times it's applied — the classic justification for allowing `GET` or `PUT`) is not the same property as replay safety: an idempotent request can still trigger a side effect — sending a notification email, incrementing an audit counter, calling a billing webhook — every time it's replayed, even though the resource's final state doesn't change. Treating "idempotent" as synonymous with "safe to replay" misses that gap. State-modifying operations, and any operation with side effects beyond the resource's own state, should be restricted to 1-RTT transport unless the application explicitly de-duplicates replays (e.g., via a request nonce or idempotency key checked server-side) on top of HTTP idempotence.

2. Encrypted Client Hello (ECH, RFC 9849)

In standard TLS 1.3, the Server Name Indication (SNI) header in ClientHello remains unencrypted, allowing network observers to monitor target domain destinations. Encrypted Client Hello (ECH), standardized as RFC 9849 in March 2026 after progressing through the draft-ietf-tls-esni series, addresses this: the client sends an unencrypted, innocuous-looking ClientHelloOuter and wraps the true handshake parameters — including the real SNI — inside an encrypted ClientHelloInner, carried as an extension and encrypted (via HPKE) under a public key published in the server’s DNS HTTPS record. ECH does not encrypt the entire ClientHello; the outer message is still sent in the clear, but the sensitive fields it would otherwise expose are hidden inside the encrypted inner payload, which is what defeats passive SNI eavesdropping.

TLS Ecosystem Mechanics

Beyond the core handshake, several mechanisms determine how TLS 1.3 actually behaves in a real deployment:

What I need to remember

TLS 1.3 completes a certificate-authenticated full handshake in one round trip without a HelloRetryRequest, mandates AEAD ciphers, and uses ephemeral key establishment for forward secrecy. PSK-only operation is permitted for resumption or external PSKs but forgoes that guarantee. 0-RTT early data is replay-vulnerable and should be restricted to operations explicitly confirmed as replay-safe, not assumed safe from HTTP idempotence alone.

Primary references