Hotshard
Open the simulatorSimulator
Networking at scale

TLS & the Handshake

How two strangers agree on a secret over a wire everyone can read.

TCP gave you a reliable byte pipe and HTTP gave you a language to speak over it — but every byte still travels in the clear. Anyone on the path (the coffee-shop Wi-Fi, the ISP, a compromised router) can read your password as you type it and change the reply before it reaches you. TLS (Transport Layer Security) is the layer that fixes this: it turns that open pipe into a private, tamper-proof channel to a server whose identity you've actually verified. The hard part isn't the encryption — it's the bootstrap: two machines that have never met, with an eavesdropper reading every byte between them, have to agree on a secret key and prove who they are. That negotiation is the TLS handshake. Understand it once and HTTPS, certificates, and the little padlock all stop being magic.

Open the simulator →~15 min read

Start here: sending a password over a wire everyone can read#

TL;DRthe 30-second version
  • TLS (Transport Layer Security, the successor to SSL) wraps a plaintext TCP connection in three guarantees: confidentiality (nobody on the path can read the bytes), integrity (nobody can change them undetected), and authentication (you're really talking to bank.com, not an impostor).
  • The core trick is the handshake: two strangers agree on a shared secret key over a wire an eavesdropper is reading — using a key exchange (Diffie–Hellman) where the secret is never actually transmitted — then switch to fast symmetric encryption for the real data.
  • Identity comes from certificates: the server presents an X.509 certificate binding its public key to its domain, signed by a Certificate Authority (CA) your device already trusts. That signature is what stops a man-in-the-middle from impersonating the server.
  • TLS 1.3 (2018) completes the handshake in one round trip and makes ephemeral, forward-secret key exchange mandatory for the full handshake, so recording today's traffic and stealing the server's key tomorrow still won't decrypt it. HTTPS is just HTTP running inside this channel.

You're on café Wi-Fi and you log in to bank.com. Your browser opens a TCP connection and sends your username and password. Here's the uncomfortable truth about plain TCP and HTTP: every byte travels in the clear. The person at the next table running a packet sniffer, the café's router, your ISP, and every network hop in between can read that password as plainly as if you'd shouted it across the room. That's the confidentiality problem.

It gets worse. A motivated attacker on the path doesn't have to just listen — they can sit in the middle and rewrite messages. Change the destination account number on a transfer. Swap the reply so your balance looks fine while money leaves. That's the integrity problem. A third problem hides underneath both: even if you could encrypt, how do you know the machine on the other end is really bank.com, and not an attacker quietly sitting in the middle relaying (and reading) everything? That attacker is called a man-in-the-middle, and shutting it out is the authentication problem.

Three problems, one layerConfidentiality (nobody reads it), integrity (nobody changes it undetected), authentication (you know who you're talking to). Encryption alone solves only the first. TLS has to solve all three at once, over a wire the attacker fully controls, between two parties who share no secret in advance. That last constraint — no pre-shared secret — is what makes it hard and interesting.

How the handshake works, at a glance#

Before any real data flows, the client and server run a quick handshake that sets up all three guarantees. You don't need the cryptographic details to use TLS well, so here's the working picture first — the actual math lives in the collapsed 'under the hood' sections below.

  • Agree on a key without sending it. Using a key exchange (Diffie–Hellman), both sides derive the same secret session key from public values they swap in the open — an eavesdropper who sees those values still can't compute the key. That key then encrypts the connection with fast symmetric encryption.
  • Prove who the server is. The server presents a certificate — a document binding its public key to its domain, signed by a Certificate Authority (CA) your browser already trusts. The client checks that signature; this is what stops an impostor from standing in for the bank.
  • Do it quickly. TLS 1.3 finishes the handshake in about one network round trip (a resumed connection can be zero), so the security cost is mostly a little latency, not CPU.
That's the whole modelAgree on a key nobody transmitted, verify who you're talking to, then switch to fast symmetric encryption. HTTPS is just HTTP running inside this channel. For an interview, that plus the cost (below) is usually enough. If you want to see how the key exchange and the certificate actually work — and why they can't be faked — the 'under the hood' sections build it up one step at a time.
Under the hood: the fast part, and the key problem it leaves

The natural first move is symmetric encryption: both sides hold the same secret key, and that one key both locks (encrypts) and unlocks (decrypts) the data. Modern symmetric ciphers — AES-GCM, ChaCha20-Poly1305 — are fast (hardware does gigabytes per second) and, as a bonus, they're authenticated: they attach a short integrity tag to the ciphertext, so any tampering is caught on decryption. (These are called AEAD ciphers — you'll see the term in cipher-suite names.) So symmetric encryption actually handles two of our three problems — confidentiality and integrity — cheaply.

There's exactly one snag, and it's the whole ballgame: both sides need the same key first. Alice's browser and bank.com have never met. If Alice picks a key and sends it over the wire, Eve (the eavesdropper) reads it in transit and now holds the key too. You can't send the shared secret over the very channel you're trying to secure. So the real question isn't 'how do we encrypt' — it's 'how do two strangers agree on a shared key while an eavesdropper watches every byte?'

The forced questionSymmetric encryption is fast and solves confidentiality + integrity — but it assumes a shared key. Establishing that key over an open, monitored wire, with no prior secret, is the problem the entire handshake exists to solve. Everything else follows from answering it.
Under the hood: agreeing on a key with Diffie–Hellman

The breakthrough is a key exchange. Each side generates a keypair: a private value it never reveals, and a matching public value it can safely broadcast. (A keypair — one secret half, one shareable half — is the whole idea behind asymmetric cryptography, and we'll use it again in a moment for identity.) The two sides swap their public values. Then a bit of math lets each one combine its own private value with the other's public value and land on the exact same result: a shared secret. An eavesdropper who sees only the two public values can't compute it. The classic construction is called Diffie–Hellman (DH).

The usual intuition is paint mixing. Alice and the server agree on a public starting color. Each stirs in a secret color of their own and sends the mixture across in the open. Each then adds their own secret color again — and both end up with the same final blend. Eve saw the two mixtures go by, but she can't 'un-mix' them to recover either secret color. Separating mixed paint is the hard part, and that one-way difficulty is what keeps the shared secret secret.

AlicebrowserServerbank.com
Both first agree on some public starting numbers, in the clear.
Alice's public share gᵃ
Server's public share gᵇ
Alice computes (gᵇ)ᵃ; server computes (gᵃ)ᵇ — same value.
Shared secret established — never sent on the wire
Diffie–Hellman: a shared secret nobody transmits

That shared secret is exactly what symmetric encryption was missing: the same key, now held by both Alice and the server, without either one ever sending it over the wire. This value — call it the Diffie–Hellman key — is run through a key-derivation step to produce the actual symmetric session keys (the keys the AEAD cipher uses to encrypt this connection's traffic). So the earlier snag — 'both sides need the same key first' — is solved. In real TLS the exchange runs over elliptic curves (ECDHE — Elliptic-Curve Diffie–Hellman Ephemeral), which is faster and needs far smaller keys than the original integer version. Notice what we've achieved: the key was never transmitted, so Eve — who recorded every byte — still doesn't have it. Confidentiality's bootstrap is solved. But a gap remains, and it's the sneaky one.

Ephemeral = forward secrecyThe 'E' in ECDHE means ephemeral: fresh DH keys for every connection, thrown away when it ends. That buys a property called forward secrecy. Suppose an attacker records your encrypted traffic today, then a year later steals the server's main private key (the long-lived one it uses to prove its identity — coming up next). They still can't decrypt the recording: the session's key came from the per-connection DH keys, and those are long gone. TLS 1.3 requires ephemeral key exchange precisely to make this guarantee universal.

The gap: Diffie–Hellman gets you a shared secret with whoever is on the other end — but it says nothing about who that is. If Eve intercepts the connection and does her own DH exchange with Alice (pretending to be the bank) and a separate one with the bank (pretending to be Alice), she ends up with two shared secrets, sits in the middle, and reads everything while both sides think they're secure. Key exchange without identity is a man-in-the-middle's paradise. We need authentication.

Under the hood: how a certificate stops an impostor

Authentication reuses that same keypair idea for a second job. The server has its own long-term keypair — separate from the throwaway DH one — keeping the private key secret and publishing the public key. A digital signature works like this. To sign, the server runs a message through a function that mixes in its private key, producing a short signature. To verify, anyone with the matching public key runs a check that passes only if that private key signed that exact message. And forging a signature without the private key isn't feasible: recovering the private key from the public one takes the same infeasible math the key exchange relied on.

So when the server signs part of the handshake and Alice checks it with the public key, a passing check proves exactly one thing: the other end holds the private key that matches this public key. That's real, but not enough on its own. Alice still has no way to know whether this public key belongs to bank.com or to Eve. Tying a public key to a real-world identity is the missing piece.

The answer is a certificate: an X.509 document that binds a public key to a domain name (bank.com), and is itself signed by a Certificate Authority (CA) — a trusted third party whose own public keys ship pre-installed in your operating system and browser (the trust store). Your device trusts a few hundred root CAs out of the box. When the server presents its certificate, Alice checks that a CA she already trusts vouched for it by signing it. Eve can't forge this: she can generate a key pair claiming to be bank.com, but no trusted CA will sign it for her — a CA issues a certificate for a domain only to someone who can prove they control it (we'll see how at Let's Encrypt below) — and a self-signed claim fails the check (that's the scary browser warning).

  • Root CAin your trust store (pre-trusted)
    • Intermediate CAsigned by the root
      • bank.com leaf certpublic key + domain, signed by intermediate
The certificate chain Alice verifies

So how does the certificate actually stop the man-in-the-middle? Walk it through:

  1. The certificate is public — Eve can copy bank.com's. But it holds only the public key; the matching private key never leaves the real bank.
  2. Proving you own a certificate means signing with its private key. Eve doesn't have it, so she can't.
  3. And the server signs the handshake transcript, not a fixed phrase Eve could replay. That transcript includes the DH shares just exchanged, so the signature is welded to this one key exchange.
  4. In a man-in-the-middle, Eve runs her own DH with Alice, so Alice's transcript carries Eve's share gᵉ, not the bank's gᵇ. The real bank never signs a transcript containing gᵉ — so any signature Eve can get is over the wrong shares, and Alice's check fails.

Eve can't forge a signature (no private key) and can't reuse a real one (wrong shares), so the handshake aborts before any data flows. Diffie–Hellman gave Alice a secret with whoever answered; the signature proves that whoever is the real bank.

Under the hood: the TLS 1.3 handshake, step by step

TLS 1.3 fuses key exchange and authentication into a single, fast negotiation. The client is optimistic — it sends its DH key share immediately, guessing the server's parameters — so that by the end of one round trip both sides have keys and the client can already send encrypted application data.

ClientbrowserServerbank.com
ClientHello + key share + cipher list
Server picks a cipher, does its half of DH, derives keys.
ServerHello + key share, {Certificate + signature}, {Finished}
Client verifies the cert chain and the signature, derives the same keys.
{Finished} + {application data}
Encrypted channel live — 1 round trip after TCP
TLS 1.3 handshake (1-RTT)
  1. ClientHello: the client sends the TLS versions and cipher suites it supports — a cipher suite is one bundle of algorithms the two sides agree to use (a key-exchange method, a symmetric cipher, and a hash) — plus a DH key share for its best-guess parameters. This is the one unencrypted flight.
  2. ServerHello: the server picks a cipher suite and sends its own key share. From the two shares, both sides now derive the shared secret and the symmetric session keys — everything after this point is encrypted.
  3. Certificate + signature: the server sends its certificate chain and a signature over the handshake transcript, proving it holds the matching private key. (Now encrypted, so eavesdroppers don't even learn which cert you got.)
  4. Finished (both sides): each sends a MAC (message authentication code — a short integrity tag keyed by the freshly-derived session key) over the whole transcript. If the transcripts don't match — because someone tampered mid-handshake or tried to downgrade the version — the Finished check fails and the connection aborts.
  5. Application data: the client verifies the certificate against its trust store and the signature, then sends real HTTP requests inside the encrypted, authenticated channel.
PredictIn TLS 1.3 the client sends its key share in the very first message, before it has seen the server's certificate. Why is that safe — isn't it committing to a key exchange with a server it hasn't authenticated yet?

Hint: What does a DH public share actually reveal? And what is the client allowed to send before the cert checks out?

The DH key share is just a public value (gᵃ); revealing it leaks nothing, so sending it early costs nothing. The client hasn't 'committed' to trusting anyone — it derives session keys from the exchange, but it will not send any sensitive application data until after it has verified the server's certificate and signature in the ServerHello flight. Authentication still gates the real data; the optimistic key share just overlaps the math with the round trip to save time. If the certificate fails to verify, the handshake aborts and nothing meaningful was exposed.

What it costs: round trips and CPU#

Security isn't free, and for TLS the dominant cost is latency, not CPU. Before any HTTPS byte flows, you pay TCP's own handshake (1 round trip, or RTT — the time for a packet to go out and a reply to come back) plus the TLS handshake on top. The version you run decides how many TLS round trips that is.

SetupTLS round tripsFirst request after…Notes
TLS 1.2, full handshake2 RTT3 RTT (incl. TCP)Two back-and-forths before data — the old default.
TLS 1.3, full handshake1 RTT2 RTT (incl. TCP)Client's early key share cuts a round trip.
TLS 1.3, resumption (0-RTT)0 RTT1 RTT (incl. TCP)Reuse a prior session; send data on the first flight.
QUIC / HTTP-30–1 RTT combined1 RTT (or 0)TLS 1.3 is folded into the transport handshake itself.

The CPU cost is real but usually secondary: the handshake does a handful of asymmetric operations (the DH exchange and the signature verification), which are far more expensive per-op than symmetric encryption — this is why the design uses asymmetric crypto only to bootstrap, then hands the bulk data to cheap symmetric AEAD. At scale you amortize the handshake cost with session resumption (skip the full exchange for returning clients) and by terminating TLS at a load balancer or CDN edge close to the user, which shrinks the RTT that dominates the bill.

Why latency dominatesA round trip to a server 100 ms away costs 100 ms of pure waiting no matter how fast your CPU is. Two TLS round trips on a mobile connection can add a quarter-second before the first byte — visible to users. That's why 1-RTT (TLS 1.3), 0-RTT resumption, and edge termination matter so much: they attack the round trips, which is where the time actually goes.
Variants: resumption, 0-RTT, and mutual TLS
  • Session resumption: after a full handshake, the server hands the client a ticket. On the next connection the client presents it and both sides reuse the earlier secret — skipping the expensive asymmetric work and a round trip.
  • 0-RTT (early data): resumption's aggressive mode — the client sends application data in its very first flight, before the handshake finishes. Saves a round trip, but because that data goes out before the fresh handshake's anti-replay protection is in place, an attacker can capture and resend it — so 0-RTT is only safe for idempotent requests like GETs, never a 'transfer money' POST.
  • Mutual TLS (mTLS): the client also presents a certificate, so both ends authenticate each other. Overkill for public websites (users don't have certs) but the backbone of zero-trust service meshes (Istio, Linkerd) where every service proves its identity to every other.
  • SNI (Server Name Indication): the client names the hostname it wants in the ClientHello, so one server IP can host many TLS sites. Historically sent in plaintext (a privacy leak of which site you're visiting); Encrypted Client Hello (ECH) closes that gap.

What TLS does and doesn't give you#

TLS protectsTLS does NOT protect
The contents of your bytes (confidentiality)That you're talking to bank.com at all — the IP and, without ECH, the SNI hostname still leak
Bytes from tampering in transit (integrity)Anything once it's decrypted at the other end — a compromised server sees plaintext
The identity of the server (authentication)Whether that verified server is actually honest — a valid cert ≠ a trustworthy operator
Past traffic if the server key later leaks (forward secrecy)Traffic metadata: packet sizes and timing can still leak information

The deepest trade-off is that TLS moves your trust rather than eliminating it. You no longer have to trust the network — that's the whole win — but you now have to trust the CA system: every root CA in your trust store can, in principle, issue a certificate for any domain. A single compromised or coerced CA can mint a valid certificate for bank.com. That's not a hypothetical (the DigiNotar breach in 2011 issued fraudulent Google certificates), and it's why Certificate Transparency exists — to make mis-issuance publicly detectable.

Encrypted ≠ safeThe padlock means 'this connection is private and the server proved its domain' — nothing more. A phishing site can get a perfectly valid Let's Encrypt certificate for evil-bank-login.com and show the same padlock. TLS authenticates the domain you connected to; it can't tell you that domain deserves your password.
TLS 1.2 vs 1.3, and where mTLS fits
DimensionTLS 1.2 (2008)TLS 1.3 (2018)
Full handshake2 round trips1 round trip
Key exchangeRSA or DH; the RSA method encrypts the secret to the server's key → no forward secrecyEphemeral (EC)DH only — forward secrecy always
Cipher suitesLarge menu, includes weak/legacy optionsSmall, vetted set; broken ciphers removed
CertificateSent in the clearSent encrypted
ResumptionSession IDs / tickets, 1-RTTTickets, and 0-RTT early data

The story from 1.2 to 1.3 is: fewer choices, safer defaults, faster. The big mechanical change is the key exchange. Alongside Diffie–Hellman, TLS 1.2 also allowed an older RSA-based method: instead of a DH exchange, the client picks the secret itself and encrypts it with the server's public key so only the server can read it. It works, but it has no forward secrecy — if that long-term key ever leaks, every past session it protected can be decrypted. TLS 1.2's other weak spot was choice: a long menu of cipher suites, some of them weak, which let an attacker force a downgrade to a breakable one. TLS 1.3 removed the RSA key exchange (making ephemeral Diffie–Hellman, and therefore forward secrecy, mandatory), cut the menu down to a small vetted set, encrypted more of the handshake, and shaved the full handshake from two round trips to one.

Mutual TLS isn't a separate version — it's an option in both. Turn on client certificates and both ends authenticate each other instead of just the server, which is why service meshes use it to give every service a verifiable identity.

TLS in the wild: HTTPS, Let's Encrypt, QUIC
  • HTTPS is literally 'HTTP inside a TLS channel' — same HTTP methods and status codes, now confidential and authenticated. HSTS (HTTP Strict Transport Security) is a header that tells browsers to only ever use HTTPS for a domain, defeating downgrade-to-HTTP attacks.
  • Let's Encrypt made TLS free and automatic via the ACME protocol: a script proves you control a domain and gets a 90-day certificate, auto-renewed. Short lifetimes shrink the window a stolen cert is useful and reduce reliance on slow revocation. This is the single biggest reason the web went from ~40% to ~95%+ HTTPS.
  • Certificate Transparency (CT): every certificate a CA issues is written to public, append-only logs. Domain owners monitor the logs and can spot a certificate they never requested — turning silent mis-issuance into something detectable.
  • QUIC / HTTP-3 builds TLS 1.3 directly into the transport (over UDP), so connection setup and encryption setup happen together in one 1-RTT (or 0-RTT) exchange — one of the reasons HTTP-3 connects faster than HTTP-2-over-TCP-over-TLS.
  • Revocation (killing a cert before it expires) remains the messy part: CRLs (big download lists) and OCSP (an online query per cert) both have availability and privacy problems, which is why the industry leans on short-lived certs and OCSP stapling instead.
Pitfalls & gotchas
Why did my browser show 'NET::ERR_CERT_DATE_INVALID'?

The certificate expired (or the client's clock is wrong). Certificates have a validity window; an expired cert can no longer be trusted because revocation and key-rotation assumptions break down. This is the #1 real-world TLS outage — a forgotten renewal — which is exactly why automated issuance (ACME/Let's Encrypt) exists.

Is a self-signed certificate 'less encrypted'?

No — the encryption is identical. What a self-signed cert lacks is authentication: no CA vouched for it, so the client can't verify the server's identity and can't rule out a man-in-the-middle. It's fine for internal testing where you control both ends; it's a security hole on the public internet.

What is a downgrade attack?

An active attacker tampers with the ClientHello to make the two sides negotiate an older, weaker protocol or cipher they can break. TLS 1.3 defends against this by covering the entire handshake transcript in the Finished MAC — if the attacker altered the negotiation, the transcripts won't match and the handshake aborts.

If I use HTTPS, is my browsing fully private?

Not entirely. TLS hides the contents and the exact URL path, but the destination IP is visible to the network, and unless Encrypted Client Hello is in use the SNI hostname (which site) leaks in the clear. Packet timing and sizes can also reveal patterns. TLS gives confidentiality of content, not full anonymity of metadata.

Why not just encrypt everything with the server's public key and skip Diffie–Hellman?

That's essentially old RSA key exchange, and it has no forward secrecy: if the server's private key is ever stolen, every past session that was recorded can be decrypted, because the session key was protected by that one long-lived key. Ephemeral DH derives a throwaway secret per connection, so a future key compromise can't unlock the past. TLS 1.3 removed RSA key exchange for exactly this reason.

QuizAn attacker records all of Alice's encrypted TLS 1.3 traffic to bank.com today, then next year manages to steal bank.com's long-term private key. Can they now decrypt last year's recording?

  1. Yes — the private key decrypts everything the server ever received.
  2. No — the session used an ephemeral Diffie–Hellman secret that was discarded, so the long-term key can't reconstruct it.
  3. Only the certificate exchange, not the application data.
  4. Yes, but only if TLS 1.2 was used.
Show answer

No — the session used an ephemeral Diffie–Hellman secret that was discarded, so the long-term key can't reconstruct it.This is forward secrecy. TLS 1.3 mandates ephemeral (EC)DH: the session keys come from a per-connection DH secret that both sides delete when the connection ends. The server's long-term private key only authenticates the handshake (it signs, it doesn't derive the session key), so stealing it later reveals nothing about past recorded sessions. Note option 4 is a trap — TLS 1.2 *can* have forward secrecy too (with ECDHE suites); it just didn't require it, whereas 1.3 does.

In an interview

TLS shows up whenever a design says 'and this connection is secured with HTTPS/mTLS.' Interviewers probe whether you understand what that actually buys and costs. Lead with the three guarantees (confidentiality, integrity, authentication), then explain the handshake as the bootstrap that establishes a shared key with a verified party over an open wire.

  • Name the split: asymmetric crypto (DH key exchange + certificate signature) to bootstrap trust and a key, then fast symmetric AEAD for the bulk data. Explaining why both exist is the money answer.
  • Mention forward secrecy and why TLS 1.3 makes ephemeral DH mandatory — it's the detail that shows you understand the threat model, not just the mechanics.
  • Know the cost: a full TLS 1.3 handshake adds 1 RTT on top of TCP; resumption/0-RTT and edge termination are how you claw that back at scale.
  • For service-to-service designs, reach for mTLS and zero-trust: every service presents a certificate, identity is cryptographic, not network-location-based.
  • Flag the trust shift: TLS moves trust from the network to the CA system, and a valid certificate proves the domain, not the operator's honesty (phishing sites have valid certs).
PredictA candidate says 'we'll put the API behind HTTPS so attackers can't see the data.' What's the crucial follow-up an interviewer wants, and what's the subtlety about where the data is protected?

Hint: Where does the TLS connection actually end, and what happens to the bytes after that point?

The follow-up: HTTPS protects data in transit between client and the TLS endpoint — but where does TLS terminate? If it terminates at the load balancer or CDN edge, the traffic from there to your backend services is a separate hop that may be plaintext unless you also secure it (mTLS or an internal TLS leg). 'Behind HTTPS' says nothing about the internal network, the database connection, or the data at rest. A strong answer names the TLS termination point and what protects each leg beyond it — end-to-end is a chain of secured hops, not one padlock.

References
References

Feedback on this topic →