Skip to content

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

  1. Authentication — prove the server is who it claims to be (via its certificate)
  2. Key agreement — both sides derive the same symmetric session key, without an eavesdropper being able to compute it too
  3. 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.