TLS deep dive
Full TLS 1.3 walkthrough: handshake, cipher suites, certificates, OCSP, session resumption, 0-RTT, mutual TLS, performance tuning, and what changed from 1.2.
The Three Goals
TLS provides three guarantees, in order of how often people forget them.
- Confidentiality. Network observers cannot read the content.
- Integrity. Network observers cannot modify the content without detection.
- Server authentication. The client knows it is talking to the real server, not a man in the middle.
It does NOT provide client authentication by default. The server has no idea who the client is at the TLS layer. Application-level auth (sessions, JWT, API keys) handles that. Mutual TLS (mTLS) optionally adds client certs.
TLS 1.3 Handshake In Detail
TLS 1.3 was a ground-up rewrite. The previous versions (1.0 through 1.2) accumulated cruft over 20 years. 1.3 removed everything that was insecure or rarely used, simplified the message flow, and cut the handshake from 2 RTTs to 1.
What is happening cryptographically.
- Client sends supported parameters and a fresh ephemeral ECDH public key (the "key_share").
- Server picks the cipher suite, generates its own ephemeral ECDH key, computes the shared secret via ECDH, derives the handshake encryption key via HKDF.
- Server sends back its key_share (so the client can compute the same shared secret), the certificate, and a signature over the handshake transcript using the certificate's private key.
- Client verifies the cert chain, verifies the signature (proving the server controls the cert's private key), and now both sides have the shared secret.
The certificate's private key is never used to derive the session key. It only signs the ephemeral public key. This is what gives forward secrecy.
Cipher Suites in TLS 1.3
TLS 1.2 had hundreds of cipher suites. TLS 1.3 has five.
- 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
In practice you use the first three. AES-GCM is faster on x86 with AES-NI. ChaCha20-Poly1305 is faster on devices without hardware AES (mobile ARM, embedded). The server should prefer the client's preferred order.
All five are AEAD (Authenticated Encryption with Associated Data). They encrypt and authenticate in one operation. No more separate MAC step, no more padding oracles like POODLE.
Certificate Validation
When the server sends its cert, the client does the following.
- Check the cert's
Not BeforeandNot Afterdates. - Check the cert's Subject Alternative Names contain the hostname. (Common Name is deprecated, do not rely on it.)
- Build the chain from the leaf cert up through any intermediates the server sent, ending at a self-signed root.
- Check that the root is in the client's trust store.
- Verify each signature in the chain.
- Check for revocation (OCSP, CRL, or OCSP Must-Staple).
The trust store is the weak point. Browsers ship the Mozilla CA list, OSes have their own. A compromised or malicious CA can issue a cert for any domain. Certificate Transparency (CT) helps: all certs from public CAs must be logged to public append-only logs. Browsers can detect mis-issuance.
Revocation: The Mess
If a private key leaks, you revoke the cert. But how do clients know? Two old mechanisms, both broken in practice.
- CRL (Certificate Revocation List): the CA publishes a list of revoked serials. Clients download it. Lists are huge and clients almost never check.
- OCSP (Online Certificate Status Protocol): client asks the CA "is this serial revoked?" Adds latency, privacy leak (CA sees what you visit), CAs often fail.
The fix is OCSP stapling: the server fetches its own OCSP response and sends it in the handshake. No extra RTT, no privacy leak. OCSP Must-Staple is a cert extension that says "fail closed if no stapled response." Few sites enable it.
In 2026 the trend is short-lived certs. Let's Encrypt issues 90-day certs. Some CAs are pushing 6-day certs. If certs only live a few days, revocation matters less because the cert dies on its own.
Session Resumption and 0-RTT
A full handshake is 1 RTT. For mobile users on high-latency links, that adds 200ms+. TLS 1.3 has two resumption mechanisms.
PSK (Pre-Shared Key) resumption: after a successful handshake, the server gives the client a session ticket (encrypted resumption state). On the next connection, the client sends the ticket. Server decrypts it, derives a new session key from the resumption secret. Cuts handshake to 1 RTT (no cert verification needed) or 0 RTT (early data).
0-RTT: the client can send application data with its first message (ClientHello), encrypted with a key derived from the resumption secret. The server processes it before any round trip. Page loads on resumed connections feel instant.
The catch: 0-RTT data is replayable. An attacker who captures the packets can replay them. The server cannot tell the difference between the original and the replay because there is no fresh server nonce in the derivation. So you must only put idempotent requests in 0-RTT. GET requests yes, POST requests no. HTTP/2 servers typically reject non-idempotent methods in early data.
Mutual TLS
By default TLS authenticates only the server. mTLS adds client certificate authentication. The server sends a CertificateRequest in the handshake, the client sends its cert and signs the transcript.
Use cases.
- Service-to-service auth in microservices. Each service has a cert from your internal CA. No API keys to leak.
- VPN-like access to internal admin panels.
- IoT devices authenticating to a backend.
Tools: SPIFFE/SPIRE, Istio, Linkerd, or roll your own internal CA with step ca. Avoid mTLS for public-facing user auth because cert distribution to end users is brutal.
Performance Tuning
The handshake is the expensive part. Things to optimize.
- TLS 1.3. Saves an RTT compared to 1.2.
- Session resumption. Saves a full handshake on repeat visits.
- OCSP stapling. Avoids an extra OCSP fetch on the client.
- ECDSA over RSA for the cert. Smaller certs, faster handshake signature.
- HTTP/2 or HTTP/3. Connection reuse means one handshake serves many requests.
- HTTP/3 / QUIC. TLS is baked into QUIC at the transport layer, eliminating a round trip versus TCP+TLS.
After the handshake, the symmetric crypto is essentially free. AES-NI on modern CPUs does 10+ GB/s per core. The "TLS is slow" myth is from the 1990s.
What Got Removed in TLS 1.3
Knowing what 1.3 killed helps you spot config bugs.
- RSA key exchange (no forward secrecy)
- Static Diffie-Hellman (no forward secrecy)
- CBC mode (BEAST, POODLE, Lucky 13)
- MD5 and SHA-1 in signatures
- RC4 (broken)
- Compression (CRIME)
- Renegotiation (used in attacks)
- DSA signatures
- Custom DH groups (weak parameters)
If your TLS scanner shows any of these, your config is from before 2015.
SNI and ECH
The Server Name Indication extension tells the server which hostname the client wants (so a server with many certs picks the right one). In TLS 1.2 and even 1.3 baseline, SNI is sent in plaintext during ClientHello. A network observer learns which sites you visit even on TLS.
Encrypted Client Hello (ECH, the successor to ESNI) encrypts the inner ClientHello including SNI. Requires DNS HTTPS records to advertise the public key. Cloudflare and Mozilla have shipped support; widespread deployment is in progress.
Common Pitfalls
- Supporting TLS 1.0 / 1.1 "for compatibility." Both are deprecated. Anything that needs them is too old to be on the internet.
- Self-signed certs in production. Use Let's Encrypt or a real CA.
- Hardcoding cert paths and forgetting renewal. Use certbot or caddy or automated cert managers.
- Disabling cert verification in clients.
verify=Falsein requests,rejectUnauthorized: falsein Node. This breaks all of TLS. - Not pinning intermediate CAs in mobile apps. App-level pinning prevents MITM via rogue CAs but also breaks if the cert chain changes. Pin the public key of your leaf or a long-lived intermediate.
Interview Soundbites
- "TLS does confidentiality, integrity, and server identity. Not client auth unless you opt into mTLS."
- "TLS 1.3 is 1 RTT, AEAD only, ECDHE only, forward secrecy by default."
- "Cert signs the ephemeral key, that is forward secrecy. Cert private key never derives the session key."
- "0-RTT is fast but replayable. Idempotent requests only."
Learn more
- Docs
- ArticleCloudflare: TLS 1.3 deep diveCloudflare
- DocsBulletproof TLS and PKI by Ivan RisticFeisty Duck
- DocsHigh Performance Browser NetworkingIlya Grigorik
- DocsMozilla SSL Config GeneratorMozilla