SSL/TLS Handshake

intermediate tls ssl handshake https security encryption

The TLS handshake is how a client and a server agree on a shared encryption key before they start sending real data. It happens at the very start of every HTTPS connection.

In simple language: before sending our password to a website, our browser and the server first do a quick “hello, here’s my ID, here’s how we’ll encrypt things” dance. That dance is the handshake.

Why It Matters

Without TLS, data goes over the wire in plaintext. Anyone on the same WiFi can read it. TLS solves three problems at once:

  1. Encryption — nobody in the middle can read the bytes.
  2. Authentication — we know we’re really talking to bank.com, not a fake.
  3. Integrity — nobody tampered with the bytes in transit.

The handshake sets all of this up.

TLS 1.2 — The Full Handshake (2-RTT)

This is the classic flow. Two round trips before any application data flows.

  1. ClientHello — client says: “Hi, I support these cipher suites and TLS versions, here’s a random number.”
  2. ServerHello + Certificate + ServerKeyExchange + ServerHelloDone — server picks a cipher, sends its X.509 certificate, sends its key exchange params, says “your turn.”
  3. ClientKeyExchange + ChangeCipherSpec + Finished — client verifies the cert, generates the pre-master secret, encrypts it with the server’s public key, switches to encrypted mode, sends a Finished message.
  4. ChangeCipherSpec + Finished — server decrypts the secret, derives the same session keys, switches to encrypted mode, sends its own Finished.

Now both sides have the same symmetric session key. Real data starts flowing.

TLS 1.3 — The Modern Handshake (1-RTT)

TLS 1.3 (RFC 8446, 2018) cuts this in half. Cipher suite negotiation is simpler. Key share is sent in the very first message.

  1. ClientHello (with key share + cipher suites) — client sends everything it can in round one.
  2. ServerHello + EncryptedExtensions + Certificate + Finished — server picks the cipher, sends its cert, derives the keys, and sends Finished. From this point onward, even the certificate is encrypted.
  3. Finished — client sends its Finished. Done.

One round trip. And with 0-RTT resumption, returning visitors can send data with the very first packet.

Side by Side

TLS 1.2 (2-RTT)
Client → ClientHello
supported ciphers, random
Server → ServerHello, Cert, KeyEx, Done
Client → KeyEx, ChangeCipher, Finished
Server → ChangeCipher, Finished
App data flows
TLS 1.3 (1-RTT)
Client → ClientHello + KeyShare
all cipher info upfront
Server → ServerHello, {Cert, Finished}
cert is already encrypted
Client → {Finished}
App data flows
0-RTT possible on resumption

Inspect a Real Handshake

# See every step of the handshake against a server
openssl s_client -connect google.com:443 -tls1_3

# Just the cert chain
openssl s_client -connect google.com:443 -showcerts < /dev/null

Why HTTPS Is Fast Now

HTTPS used to have a bad reputation for being slow. Three things changed that:

  • TLS 1.3 cut the handshake from 2-RTT to 1-RTT.
  • Session resumption (PSK) skips the handshake entirely on reconnects.
  • HTTP/2 and HTTP/3 multiplex many requests over one TLS session, so we pay the handshake cost once.

In practice, the TLS overhead on a modern site is a few milliseconds at most.

Common Gotcha

People often confuse the handshake with the ongoing encryption. The handshake uses asymmetric crypto (slow) only to agree on a shared key. After that, all real traffic uses symmetric crypto (fast). We’ll cover that distinction in the next note.