How the SSL/TLS Handshake Works
"SSL" is the name everyone still uses; the actual protocol in use today is TLS (SSL was its predecessor and is considered broken/deprecated). The handshake is what happens before any encrypted application data flows — it establishes who you're talking to and what key you'll both use to protect the conversation.
What the handshake needs to achieve¶
- Authentication — prove the server is who it claims to be (via its certificate)
- Key agreement — both sides derive the same symmetric session key, without an eavesdropper being able to compute it too
- Integrity — detect if anything in the handshake was tampered with
TLS 1.2 handshake (the classic version)¶
Client Server
|-------- ClientHello ------------------>|
|<------- ServerHello --------------------|
|<------- Certificate --------------------|
|<------- ServerKeyExchange --------------|
|<------- ServerHelloDone ----------------|
|-------- ClientKeyExchange ------------->|
|-------- ChangeCipherSpec + Finished --->|
|<------- ChangeCipherSpec + Finished ----|
|========= encrypted application data ====|
- ClientHello — supported TLS versions, cipher suites, and a random value
- ServerHello — the cipher suite the server picked, its own random value
- Certificate — the server's X.509 certificate, which the client validates against a chain of trust up to a root CA it already trusts
- Key exchange — both sides use the exchanged parameters (typically ECDHE — elliptic-curve Diffie-Hellman) to independently compute the same pre-master secret, which both then use to derive identical session keys
- Finished — a MAC over the whole handshake so far, proving nothing was tampered with, sent under the now-active encryption
That's 2 round trips before any real data moves.
Certificate validation, briefly¶
The browser checks: - Is the certificate signed by a CA it trusts (chaining up to a root CA in its trust store)? - Is the certificate's domain name (or SAN) a match for the site being visited? - Is it within its validity window, and not revoked?
If any of that fails, you get the browser's "connection is not private" warning — that's the authentication half of TLS doing its job.
TLS 1.3: faster and stricter¶
TLS 1.3 cut the handshake down to 1 round trip:
- The client guesses/sends its preferred key-exchange parameters in the ClientHello, instead of waiting for the server to ask
- The server can respond with its certificate and Finished message immediately after
- Weak/legacy ciphers (static RSA key exchange, older hash functions) were removed outright — TLS 1.3 only offers modern, forward-secret cipher suites
Why "forward secrecy" matters¶
Because the session key is derived via Diffie-Hellman (not just encrypted with the server's long-term private key), compromising the server's private key later doesn't let anyone decrypt past traffic they may have recorded. Each session's key is ephemeral and independent.
Seeing it yourself¶
openssl s_client -connect example.com:443 -tls1_3
This prints the negotiated cipher suite and the full certificate chain — the concrete result of everything above.