What Is an SSL/TLS Handshake? Step-by-Step
Every time you load an https:// page, your browser and the server run a TLS handshake before a single byte of your actual request is sent. It's the negotiation that turns an open TCP connection into an encrypted, authenticated channel — and understanding it is the key to debugging the handshake failures that break HTTPS.
This guide walks through the handshake step by step, explains what each side proves, and covers how TLS 1.3 made it dramatically faster.
What the Handshake Accomplishes
"SSL" is the old name; the modern protocol is TLS (Transport Layer Security), with TLS 1.2 and TLS 1.3 in active use. People still say "SSL handshake," but it's TLS underneath.
The handshake has three jobs, completed before any application data flows:
- Agree on a cipher suite — which encryption and hashing algorithms both sides support.
- Authenticate the server — prove the server is who it claims to be, using its certificate.
- Establish a shared secret — derive a symmetric session key that only the two parties know, used to encrypt the rest of the conversation.
It happens right after the TCP connection opens and before the HTTP request is sent.
The TLS 1.2 Handshake, Step by Step
The classic handshake takes two round trips:
1. ClientHello. The browser opens with: the TLS versions it supports, a list of cipher suites it can use, a random number, and extensions (including SNI — the hostname it wants, so the server knows which certificate to present).
2. ServerHello. The server replies with its choice: the selected TLS version, the chosen cipher suite, and its own random number.
3. Certificate. The server sends its certificate chain — its leaf certificate plus any intermediates — so the client can verify its identity. The client checks that the certificate is valid, unexpired, matches the hostname, and chains up to a trusted root CA. (A broken chain here is the most common handshake failure — see What Is an SSL Certificate Chain?.)
4. Key exchange. Using the certificate's public key and an algorithm like ECDHE, both sides contribute to deriving the same session key without ever transmitting it. Modern suites use ephemeral keys for forward secrecy — even if the server's private key leaks later, past sessions stay safe.
5. Finished. Both sides send a "Finished" message encrypted with the new session key. If each can decrypt the other's, the keys match and the handshake succeeds. From here, all data is encrypted symmetrically.
TLS 1.3: One Round Trip
TLS 1.3 (2018) streamlined the handshake to a single round trip by having the client guess the key-exchange parameters in its first message:
- The ClientHello includes its key-share immediately.
- The server responds with its key-share, certificate, and Finished — all at once.
- The client can start sending encrypted data after just one round trip.
TLS 1.3 also dropped every weak/legacy cipher (RSA key exchange, CBC modes, RC4), so the negotiation is both faster and safer. It even supports 0-RTT resumption, where a returning client sends data in its very first packet. If you're choosing what to support, TLS 1.3 should be your default.
Inspecting the Certificate Side
Most handshake failures come down to the certificate exchanged in step 3. To see exactly what a server is presenting:
- The SSL Checker connects to a live domain and reports the certificate's issuer, expiry, and chain status — the fastest way to confirm a server's handshake-relevant config.
- The SSL Certificate Decoder takes a PEM certificate and shows its subject, SANs, validity dates, and signature algorithm, so you can verify the hostname matches and the cert isn't expired.
- For raw chain files, the Certificate Decoder auto-detects and parses any certificate format.
Common Handshake Failures
Certificate expired or not yet valid. The client rejects the cert in step 3. Check validity dates with the SSL Decoder.
Hostname mismatch. The certificate's SANs don't include the hostname the client requested. The cert is valid but for the wrong name.
Incomplete chain. The server sent its leaf cert but not the intermediate(s), so the client can't build a path to a trusted root. This causes the classic "unable to get local issuer certificate" error — see the dedicated fix guide.
Protocol/cipher mismatch. An old client and a modern server (or vice versa) share no common TLS version or cipher suite. Typically a client stuck on TLS 1.0/1.1 hitting a TLS 1.2+-only server.
Untrusted root. The certificate chains to a CA the client doesn't trust — common with self-signed or internal corporate CAs.
Quick Reference
- The TLS handshake negotiates ciphers, authenticates the server via its certificate, and derives a shared session key — all before any data flows.
- TLS 1.2 takes two round trips; TLS 1.3 takes one and removed all legacy ciphers — prefer it.
- Server identity is proven by its certificate chain in the handshake; chain problems are the #1 failure.
- Inspect a live server with the SSL Checker and decode certificates with the SSL Decoder.
- Most failures: expired cert, hostname mismatch, incomplete chain, protocol mismatch, or untrusted root.