The idea: the same job with one round trip fewer

A TLS handshake has three jobs: agree on a secret key, prove that the server really is shop.example, and check that nobody changed the messages on the way. TLS 1.2 (2008) and TLS 1.3 (2018) both do all three, but TLS 1.3 needs one round trip (RTT) less, encrypts most of the handshake, and drops the key exchange that had no forward secrecy. The page runs both on the same network, RTT = 50 ms, on a TCP connection that is already open, and draws each as a time-down diagram: client line, network, server line, one row per one-way trip.

Two time-down diagrams. Left, TLS 1.2: ClientHello; ServerHello, Certificate, ServerKeyExchange, ServerHelloDone in clear; ClientKeyExchange, ChangeCipherSpec, Finished; ChangeCipherSpec, Finished; then GET at 100 ms and 200 OK at 150 ms. Right, TLS 1.3: ClientHello with key_share; ServerHello with key_share and encrypted EncryptedExtensions, Certificate, CertificateVerify, Finished; then Finished and GET at 50 ms and 200 OK at 100 ms.
TLS 1.2 sends its request after 2 RTT and shows the certificate to anyone on the path; TLS 1.3 sends it after 1 RTT and encrypts everything after ServerHello.

Box colours say what an eavesdropper can read: grey flights are all in clear, blue ones carry encrypted handshake messages, green ones carry encrypted application data. In the message lists {…} marks an encrypted message, as in RFC 8446. Under each diagram the eavesdropper box lists what it has recorded.

Why TLS 1.3 saves a round trip

In TLS 1.2 the client first asks which cipher suite the server wants. The server's answer (ServerHello … ServerHelloDone) says how keys will be agreed, and only then does the client send its part of the key exchange (ClientKeyExchange). Both sides switch to encryption with ChangeCipherSpec and confirm the handshake with Finished. The client may send GET / only after the server's Finished: 2 RTT, response at 150 ms (Demo: full handshake, 2 RTT vs 1 RTT).

TLS 1.3 removes the question. It allows only a few key-exchange groups, so the client guesses one (almost always x25519) and puts its public key_share in the ClientHello. The server answers with its own share, and after that one message both sides can compute the keys. The client sends Finished and GET / together after 1 RTT; the response is back at 100 ms. If the guess is wrong, the server answers HelloRetryRequest and the handshake costs 2 RTT after all.

TLS 1.2TLS 1.3
new visitor: request leaves at2 RTT (100 ms)1 RTT (50 ms)
new visitor: response at3 RTT (150 ms)2 RTT (100 ms)
returning visitor: request leaves at1 RTT (session ticket)0 RTT (early data)
returning visitor: response at2 RTT (100 ms)1 RTT (50 ms)
key exchangeRSA, DHE or ECDHEDHE or ECDHE only
eavesdropper reads (full handshake)8 messages, the certificate among themClientHello and ServerHello

Which messages are encrypted

In TLS 1.2 the keys exist only after ClientKeyExchange, so the whole handshake before it travels in clear: the server's Certificate, its signed key share, the client's key share. Only the two Finished messages are encrypted. Anyone on the path learns exactly which certificate (and so which site) the server showed. In TLS 1.3 the keys exist right after ServerHello, so EncryptedExtensions, the Certificate, CertificateVerify and Finished are all encrypted with handshake keys. What is left in clear is the two Hellos, and in the ClientHello the server name (SNI), which Encrypted Client Hello (ECH) now hides as well.

RSA key exchange and forward secrecy

With RSA key exchange the TLS 1.2 client picks a random pre-master secret and encrypts it with the public RSA key in the server's certificate. Only the server can decrypt it, so the handshake is safe today. But the same long-term key protects every session. An attacker who records traffic and gets the private key years later, from a stolen backup or a court order, decrypts the recorded pre-master secrets and reads every session (Demo: RSA key exchange, then the key leaks). The connection has no forward secrecy.

With ECDHE (ephemeral elliptic-curve Diffie-Hellman) each side makes a fresh key pair for this one connection, sends the public half, and deletes the private half after the handshake. The server's long-term key only signs its share (ServerKeyExchange in 1.2, CertificateVerify in 1.3) to prove who sent it. A leaked key then lets an attacker impersonate the server from now on, but it does not open anything recorded before (Demo: ECDHE on both, then the key leaks). TLS 1.2 could do ECDHE too; TLS 1.3 made it the only way.

Left, RSA key exchange: the pre-master secret is encrypted with the server's long-term key; when the key leaks the recording decrypts, marked with a cross. Right, ECDHE: the long-term key only signs the ephemeral share; the ephemeral secrets are deleted; when the key leaks the recording stays sealed, marked with a check.
With RSA key exchange the server's key unlocks every recorded session; with ECDHE it only ever signed, so old recordings stay sealed.

Resumption, 0-RTT and replay

A returning client can skip the certificate. In TLS 1.2 it sends the session ticket it got last time; the server answers ServerHello, ChangeCipherSpec, Finished, and the request leaves after 1 RTT. In TLS 1.3 the ticket becomes a pre-shared key (PSK), and the client may encrypt data with a key derived from it right away: GET / rides in the first flight as 0-RTT early data and the response is back after 1 RTT (Demo: resumption, 1 RTT vs 0-RTT).

Early data has a price. It depends only on the ticket, not on anything fresh from the server, so a recorded copy decrypts again. An attacker who replays a POST /buy sent in 0-RTT places the order twice. In TLS 1.2 the request is sent after the server's fresh random has gone into the keys, so a copied record fails its integrity check in any other connection (Demo: 0-RTT replay attack). Browsers therefore send only safe requests in early data, servers keep anti-replay state (single-use tickets, a cache of recent ClientHellos), and a server that is unsure answers 425 Too Early. The QUIC Handshake vs TCP + TLS 1.3 shows the same 0-RTT inside QUIC.

What else TLS 1.3 removed

TLS 1.3 kept only AEAD ciphers (AES-GCM, ChaCha20-Poly1305) and dropped everything that had led to attacks in 1.2: CBC mode with MAC-then-encrypt (Lucky 13, POODLE), RC4, static RSA and static DH, compression (CRIME), renegotiation, and custom DH groups. A cipher suite name shrank from TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 to TLS_AES_128_GCM_SHA256, because the key exchange and the signature are no longer part of it. See How an HTTPS Connection Is Established for the keys message by message and TLS Certificate Chain and Revocation for how the client checks the certificate.

What the page leaves out

The TCP handshake before TLS (1 more RTT on both sides), TLS False Start (a TLS 1.2 client may send data with its Finished, saving a round trip), HelloRetryRequest, the key schedule (HKDF, handshake and traffic secrets), session IDs as the other 1.2 resumption method, session ticket keys that weaken forward secrecy in 1.2, client certificates, the middlebox compatibility mode that makes TLS 1.3 look like a 1.2 resumption, downgrade protection, record sizes and padding, and post-quantum hybrid key shares.