TLS 1.3 vs TLS 1.2
Key Takeaways
- TLS 1.3 completes the handshake in 1-RTT vs 2-RTT in TLS 1.2 — measurable latency improvement on every new connection
- RSA key exchange, CBC ciphers, and SHA-1 are removed entirely — only AEAD ciphers with forward secrecy remain
- The server certificate is encrypted in TLS 1.3, preventing passive observers from seeing which site you're connecting to
- Middleboxes (firewalls, DLP, IDS) that inspect TLS 1.2 traffic often break TLS 1.3 connections — test before enforcing
TLS 1.3 (RFC 8446, published August 2018) is a major redesign of the TLS protocol, not an incremental update. It removes entire categories of insecure cryptographic options, reduces handshake latency from two round trips to one, and encrypts more of the handshake itself. TLS 1.2 (RFC 5246, 2008) remains widely deployed but carries legacy baggage — cipher suites that should never be used, optional features that create downgrade attacks, and a slower handshake that costs real latency on every new connection.
Why it matters
- Reduced attack surface — TLS 1.3 removed RSA key exchange (no forward secrecy), CBC mode ciphers (BEAST, Lucky13, POODLE), RC4, 3DES, MD5, SHA-1, static DH, and compression. These aren’t deprecated — they’re gone from the protocol entirely.
- Mandatory forward secrecy — every TLS 1.3 connection uses ephemeral key exchange (ECDHE or DHE). If the server’s long-term key is later compromised, past recorded sessions remain encrypted. TLS 1.2 allowed RSA key transport, which has no forward secrecy.
- 1-RTT handshake — TLS 1.3 sends the client’s key share in the first message, allowing the server to compute the shared secret immediately. TLS 1.2 requires an extra round trip for key exchange negotiation.
- Encrypted certificate — in TLS 1.3, the server’s certificate is sent after the handshake keys are derived, so it’s encrypted. In TLS 1.2, the certificate is sent in plaintext — any network observer can see which site you’re connecting to.
- Simpler cipher suite structure — TLS 1.3 has only 5 cipher suites. TLS 1.2 has hundreds of combinations, many insecure. Less choice means fewer misconfiguration opportunities.
How it works
TLS 1.3 handshake (1-RTT):
- Client sends
ClientHellowith key shares (X25519, P-256) and supported ciphers - Server selects cipher and key share, responds with
ServerHello - Server sends encrypted: Certificate, CertificateVerify, Finished
- Client validates certificate chain and server signature
- Client sends Finished — application data flows immediately
TLS 1.2 handshake (2-RTT):
- Client sends
ClientHellowith cipher suites - Server responds with
ServerHello+ Certificate (plaintext) - Server sends
ServerKeyExchange(if using ECDHE) +ServerHelloDone - Client sends
ClientKeyExchange+ChangeCipherSpec+Finished - Server sends
ChangeCipherSpec+Finished - Application data flows
The extra round trip in TLS 1.2 adds 50-150ms on typical internet connections. On mobile networks or intercontinental links, it’s 200-400ms.
In real systems
Nginx — enabling TLS 1.3 alongside 1.2:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off; # Let client choose in TLS 1.3
ssl_ecdh_curve X25519:P-256:P-384;
Checking negotiated version:
# Verify TLS 1.3 is negotiated
openssl s_client -connect example.com:443 -tls1_3
# Output includes: Protocol : TLSv1.3
# Cipher : TLS_AES_256_GCM_SHA384
# Force TLS 1.2 to test fallback
openssl s_client -connect example.com:443 -tls1_2
AWS ALB — supports TLS 1.3 via the ELBSecurityPolicy-TLS13-1-2-2021-06 security policy. Older policies only support TLS 1.2. You must explicitly select a TLS 1.3 policy.
Java applications — Java 11+ supports TLS 1.3. Java 8 does NOT (unless using a backport). If your backend services run Java 8, they cannot negotiate TLS 1.3 — the connection falls back to TLS 1.2 or fails if 1.2 is disabled.
Where it breaks
Middlebox interference — enterprise firewalls, DLP appliances, and IDS systems that perform TLS inspection often rely on seeing the plaintext certificate in TLS 1.2 to make routing/filtering decisions. TLS 1.3 encrypts the certificate, breaking these devices. Some middleboxes corrupt the handshake trying to parse it, causing connection failures. Palo Alto, Fortinet, and others have released firmware updates, but older devices may never support TLS 1.3 inspection properly.
Legacy client incompatibility — Windows 7 (without updates), Java 7/8, Android 4.x, and older embedded systems don’t support TLS 1.3. If you disable TLS 1.2 entirely, these clients can’t connect at all. Most deployments keep TLS 1.2 enabled as a fallback, but this means you’re still exposed to TLS 1.2-specific attacks on those connections.
0-RTT replay vulnerability — TLS 1.3’s 0-RTT resumption sends application data in the first flight, but this data can be replayed by an attacker. If your application processes non-idempotent requests (POST, PUT, DELETE) in 0-RTT early data without checking the Early-Data header, you have a replay vulnerability. Most servers enable 0-RTT without implementing replay protection at the application layer.
Operational insight
The biggest operational surprise during TLS 1.3 migration isn’t client compatibility — it’s network infrastructure. Organizations discover that their corporate proxy, WAF, or load balancer silently downgrades or breaks TLS 1.3 connections. The symptom is intermittent connection failures that only affect certain network paths (users behind the corporate proxy fail, direct connections work). Debugging requires packet captures at multiple points to identify where the handshake is being corrupted. Always test TLS 1.3 through your full network path — not just directly to the server.
Related topics
Ready to Secure Your Enterprise?
Experience how our cryptographic solutions simplify, centralize, and automate identity management for your entire organization.