TLS 1.2 vs 1.3: 1-RTT handshake, simplified cipher suites, and the 0-RTT replay risk

5 min read

TLS 1.3 became RFC 8446 in August 2018 and now powers more than 90% of HTTPS connections. The differences from 1.2 are not merely “new algorithms added” — the handshake itself is redesigned, vulnerable features are removed, cipher suites are cleaned up. This article walks through the mechanism and operational consequences.

Handshake round-trips

The most visible difference is round-trip count for a fresh connection.

TLS 1.2: 2 round-trips

Client                                  Server
  |                                       |
  |---- ClientHello -------------------->|
  |<--- ServerHello, Certificate,         |
  |     ServerKeyExchange, ServerHelloDone|
  |---- ClientKeyExchange,                |
  |     ChangeCipherSpec, Finished ------>|
  |<--- ChangeCipherSpec, Finished --------|
  |---- Application Data ---------------->|

The client cannot send application data until 2 RTTs have elapsed. To a server on the other side of the planet (~200ms RTT), that’s 400ms of handshake.

TLS 1.3: 1 round-trip

Client                                  Server
  |                                       |
  |---- ClientHello (with key share) --->|
  |<--- ServerHello, EncryptedExtensions, |
  |     Certificate, CertificateVerify,   |
  |     Finished --------------------------|
  |---- Finished, Application Data ------>|

The client sends key-share material in ClientHello alongside the version negotiation. One RTT suffices. Application data piggybacks on Finished.

That’s a 200ms saving for far-side connections. Time to first byte improves noticeably, especially on mobile and high-latency links.

Cipher suite simplification

TLS 1.2 naming

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

Multiple components concatenated:

ComponentExampleMeaning
Key exchangeECDHEelliptic-curve Diffie-Hellman
AuthenticationRSARSA certificates
CipherAES_128_GCMAES-128 in GCM mode
MACSHA256SHA-256

There were 100+ combinations, including rarely-used and weak options (RC4, 3DES, MD5, SHA-1, EXPORT family). Backwards-compatibility weakness left the door open to misconfiguration choosing weak ciphers.

TLS 1.3 naming

TLS_AES_128_GCM_SHA256

Just cipher + MAC. Key exchange and authentication are negotiated separately.

The entire cipher-suite list is five entries:

TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_CCM_SHA256
TLS_AES_128_CCM_8_SHA256

All are AEAD (Authenticated Encryption with Associated Data). No room for misconfiguration. RC4, 3DES, all CBC modes are gone.

Removed features

TLS 1.3 dropped:

  • Static RSA key exchange (no forward secrecy) → ECDHE required.
  • DSA authentication (vanishingly used).
  • MD5 / SHA-1 hashes (collision-vulnerable).
  • CBC modes (Lucky 13 attack vector).
  • RC4 (multiple vulnerabilities).
  • EXPORT ciphers (FREAK attack vector).
  • Compression (CRIME attack vector).
  • Non-AEAD cipher suites.

These were the substrate for nearly every TLS attack of the past decade — POODLE, BEAST, Lucky 13, FREAK, Logjam — removed at the spec level.

0-RTT mode (optional)

TLS 1.3 supports zero round-trip application data on resumed connections:

Client                                  Server
  |                                       |
  |---- ClientHello (PSK) +               |
  |     0-RTT Application Data ---------->|
  |<--- ServerHello, ... Finished, ------|
  |     Server Application Data           |

Using a Pre-Shared Key (PSK) derived from a prior session, the client sends application data in the very first packet. No RTT spent on handshake.

0-RTT replay risk

0-RTT data has weaker forward-secrecy guarantees and can be replayed by attackers — the server cannot tell the duplicate from the original. So 0-RTT must be restricted to idempotent operations:

  • ✓ GET requests.
  • ✗ POST /transfer-money and other side-effect operations.

Production servers (nginx, HAProxy, Cloudflare) expose options to only allow 0-RTT for idempotent methods.

Certificate handling

Encrypted server certificates

In TLS 1.2 the server certificate is sent in the clear. tcpdump reveals which hostname you’re connecting to.

In TLS 1.3 the certificate is sent after the encryption is set up, so a network observer can’t see it. (SNI is a separate concern — covered next.)

Encrypted Client Hello (ECH)

The ClientHello includes SNI (Server Name Indication) — “which server are you connecting to” — in cleartext, even in TLS 1.3. Encrypted Client Hello (ECH) covers that.

ECH is still experimental, partially deployed in Cloudflare and Firefox. Full adoption is years out.

Operational impact

Server-side TLS 1.3

Nginx 1.13.0+, Apache 2.4.37+ support TLS 1.3 with OpenSSL 1.1.1+.

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# TLS 1.3 cipher suites configured separately via ssl_conf_command

Client-side

Major browsers — Chrome 70+, Firefox 63+, Safari 12.1+ — all support TLS 1.3. Disabling TLS 1.2 is roughly equivalent to dropping IE 11 / very old mobile.

Certificate selection

TLS 1.3 still works with RSA certificates, but ECDSA certificates are smaller and faster in the handshake. Let’s Encrypt issues ECDSA — pick that for new domains.

Real benchmarks

Connection-time savings from TLS 1.2 → 1.3:

ScenarioTLS 1.2TLS 1.3Saved
Same datacenter (5ms RTT)10ms5ms5ms
Within country (30ms RTT)60ms30ms30ms
Intercontinental (150ms RTT)300ms150ms150ms
0-RTT resume60ms (TLS 1.2)0ms≥60ms

“First connection takes hundreds of ms; resume is zero” is a significant UX win for e-commerce bounce rates and search rankings.

Pitfalls

1. Middlebox compatibility

Corporate proxies / SSL inspection appliances sometimes mangle TLS 1.3. “Works at home, breaks at work” is the classic symptom.

TLS 1.3 includes a compatibility mode that disguises the handshake to look like 1.2 to confused middleboxes. Effective in most cases but not universal.

2. SSLv3 / TLS 1.0 / TLS 1.1 still present

Enabling TLS 1.3 doesn’t help if 1.0 / 1.1 / SSLv3 are still accepted — attackers can downgrade. (TLS 1.3 has stronger downgrade-protection, but still.) Disable everything below 1.2.

3. Both endpoints must support 1.3

The client and server both need 1.3 to negotiate it. Server-side enablement alone doesn’t guarantee 1.3 in production.

Summary

TLS 1.3 is not just a version bump but a handshake redesign, a vulnerable-feature purge, and a cipher-suite cleanup. The 1-RTT initial handshake saves a round trip; 0-RTT eliminates resume latency entirely (with the replay caveat); the five-entry cipher-suite list removes misconfiguration footguns. Enabling TLS 1.3 server-side and disabling pre-1.2 versions is the modern minimum.