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 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
- 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 ofkey_share. - 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
Finishedmessage. 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. - Encrypted Extensions & Certificate: All subsequent handshake messages are encrypted using the derived handshake key. Server sends its X.509 certificate and
CertificateVerifysignature, then its ownFinishedmessage. At this point the server can already derive its application traffic secret — itsDerive-Secretcall only needs the transcript through the server’s ownFinished, which is why TLS 1.3 permits the server to send 0.5-RTT application data before the client’s flight arrives. - Client Finished: The client verifies the server’s handshake transcript, derives its own handshake MAC, and sends its
Finishedmessage (preceded by the client’sCertificate/CertificateVerifyonly if the server requested client authentication). Once the client’sFinishedis added to the transcript, both sides can derive the resumption secret, which specifically requires the transcript through the client’sFinished(unlike the application traffic secrets, which only needed the transcript through the server’sFinished) — 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.
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 a “cipher suite” means in TLS 1.3: TLS 1.2 cipher suite names (e.g.,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) bundled key exchange, authentication, bulk cipher, and hash into one negotiated unit. TLS 1.3 splits this apart: the cipher suite now names only the AEAD algorithm and hash (e.g.,TLS_AES_256_GCM_SHA384), while key exchange (supported_groups/key_share) and authentication (the signature algorithm used inCertificateVerify, viasignature_algorithms) are negotiated as separate, independent extensions. A TLS 1.3 “cipher suite” is a narrower concept than its TLS 1.2 namesake. - ALPN (Application-Layer Protocol Negotiation, RFC 7301): A
ClientHelloextension listing application protocols the client supports (e.g.,h2for HTTP/2,http/1.1); the server picks one and returns its choice inEncryptedExtensions. This is how a single HTTPS port (443) serves both HTTP/1.1 and HTTP/2 clients without a separate handshake round-trip to negotiate the application protocol afterward. - Session resumption via tickets: Rather than repeating a full handshake, TLS 1.3 lets the server issue one or more opaque
NewSessionTicketmessages (post-handshake). The ticket itself doesn’t necessarily contain the resumption secret directly — it’s implementation-defined and opaque to the client, either a reference into server-side session state or self-contained encrypted state. The actual resumption PSK is derived from the connection’sresumption_master_secrettogether with a per-ticketticket_nonceviaHKDF-Expand-Label, so each issued ticket yields a distinct PSK even though every ticket for a connection traces back to the same resumption secret. A returning client presents a ticket via thepre_shared_keyextension, letting both sides skip straight to a PSK-based (optionally PSK+DHE) abbreviated handshake. Tickets should be short-lived and, ideally, single-use or anti-replay-protected server-side, since ticket-based resumption withoutpsk_dhe_keforgoes forward secrecy for that resumed session (see the version matrix above). - Client authentication / mTLS: The server can request a client certificate via
CertificateRequest; the client responds with its ownCertificateandCertificateVerifyinside the client’s encrypted post-ServerHello flight described in step 4. Mutual TLS (mTLS) is this mechanism used for service-to-service or zero-trust network authentication, where both directions authenticate via certificates rather than relying solely on server-side authentication plus an application-layer credential. - HelloRetryRequest (HRR): If the server doesn’t support any group the client offered a
key_sharefor (or wants a different one), it responds with aHelloRetryRequestinstead ofServerHello, asking the client to resendClientHellowith an acceptable group. This costs an extra round trip (making that handshake 2-RTT instead of 1-RTT) but lets the server participate in group selection without requiring the client to guess correctly up front or send key shares for every group it supports. - KeyUpdate: For long-lived connections, either side can send a
KeyUpdatemessage to ratchet the traffic keys forward — deriving fresh application traffic keys from the current ones via a one-way HKDF step — without a full re-handshake. This bounds how much ciphertext is protected under any single key (useful for staying within AEAD’s per-key data limits on very long connections) and protects earlier key generations after the fact, provided the superseded secrets are actually erased. It does not provide post-compromise recovery: because each new generation is derived deterministically from the current one, an attacker who holds the current traffic secret can derive every later generation too —KeyUpdateratchets existing key material forward, it doesn’t inject the fresh entropy a new (EC)DHE exchange would. - TLS vs. QUIC boundary: As noted above, HTTP/3 runs over QUIC, which uses TLS 1.3 only for its handshake and key negotiation (RFC 9001) — QUIC then does its own packet protection and has its own loss-recovery and multiplexing layer entirely separate from the TCP-carried TLS record layer HTTP/1.1 and HTTP/2 use.
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
- RFC 9846: The Transport Layer Security (TLS) Protocol Version 1.3 — IETF RFC 9846 (a backward-compatible update that obsoletes RFC 8446, the original TLS 1.3 specification)
- RFC 9849: TLS Encrypted Client Hello — IETF RFC 9849
- RFC 8996: Deprecating TLS 1.0 and TLS 1.1 — IETF RFC 8996