TLS: how the padlock works
What the 's' in https actually buys you — confidentiality, integrity, and authenticity as three separate guarantees — how asymmetric and symmetric crypto combine, the TLS 1.3 one-round-trip handshake byte by byte, what a certificate really is and why your browser trusts it, SNI, session resumption and 0-RTT's replay caveat, and exactly what the padlock does and does not promise.
TLS: how the padlock works
You've seen the padlock in the address bar ten thousand times. You know it means "https, secure." But secure against what, and how? In the fetch lesson we said TLS "negotiates encryption" and runs a handshake after TCP. This lesson opens that box — because "the padlock" bundles three distinct guarantees, uses two entirely different kinds of cryptography to deliver them, and promises something narrower than most people assume.
Start from the threat. Your request to api.hisaab.measdev.me crosses a dozen networks you don't control: the coffee-shop wifi, the ISP, backbone routers, the data center's edge. Anyone on that path can, in principle, read every byte, change it in flight, or pretend to be the server. TLS (Transport Layer Security — the "S" in HTTPS) makes all three attacks fail. Over plain HTTP, all three succeed trivially.
Three guarantees, not one
"Secure" is vague. TLS delivers three separate, nameable properties, and it's worth keeping them apart because they defend against different attacks:
- Confidentiality — nobody on the path can read your data. This is encryption in the everyday sense. Without it, your
Authorization: Bearertoken is plaintext to every router it passes. - Integrity — nobody can modify your data undetected. Even encrypted data could in theory be tampered with; TLS attaches an authentication tag to every record so any flipped bit is caught and the connection dies. This stops an attacker from, say, changing the amount in a request even if they can't read it.
- Authenticity — you're actually talking to the real server, not an impostor who intercepted the connection. This is the one people forget, and it's the one that makes the other two meaningful: encrypting a channel to an attacker who's impersonating your server protects nothing.
Hold all three. The handshake below exists to establish exactly these, in this order of subtlety: authenticity via certificates, then confidentiality and integrity via freshly agreed keys.
Two kinds of crypto, and why TLS needs both
There are two families of cryptography, with opposite tradeoffs, and TLS uses each for what it's good at.
Symmetric crypto uses one shared secret key to both encrypt and decrypt. It's fast — CPUs have hardware AES instructions and encrypt gigabytes per second. The problem is obvious: both sides need the same key, and you can't send a key over a channel an attacker is reading, or they get it too. A great lock with an impossible key-delivery problem.
Asymmetric crypto (public-key) uses a pair of mathematically linked keys: a public key you hand to anyone, and a private key you never share. What one encrypts, only the other can decrypt; what the private key signs, the public key can verify. This solves key delivery — you can safely publish a public key — but it's slow, far too slow for a whole conversation.
So TLS combines them, and this is the central trick: use slow asymmetric crypto once, at the start, purely to agree on a shared symmetric key; then use fast symmetric crypto for all the actual data. (Modern TLS doesn't literally encrypt a key with the server's public key — it uses a Diffie-Hellman key exchange, where both sides mix public "key shares" to derive the same secret without ever sending it. Same purpose: bootstrap a shared symmetric key over a public channel.) The asymmetric part also does double duty — the server's certificate and signature prove authenticity at the same time.
The TLS 1.3 handshake, step by step
Here's the modern handshake. It runs after TCP's three-way handshake has completed, on top of the connection TCP opened. TLS 1.3 is designed to need only one round trip:
Client Server
│ (TCP already established underneath) │
│ │
│ ClientHello │
│ • TLS version, cipher suites I support │
│ • my Diffie-Hellman KEY SHARE (a public value) │
│ • SNI: "api.hisaab.measdev.me" │
├─────────────────────────────────────────────────────────►
│ │
│ ServerHello │
│ • chosen cipher │
│ • server's DH KEY SHARE │
│ ── both sides can now derive the ── │
│ ── shared symmetric key here ── │
│ {Certificate} (chain) │
│ {CertificateVerify} (signature) │
│ {Finished} │
│◄─────────────────────────────────────────────────────────
│ │
│ {Finished} │
│ {GET /groups ...} ← application data, encrypted │
├─────────────────────────────────────────────────────────►
│ │(Braces {...} mark messages already encrypted with the freshly derived key.) Walk it:
- ClientHello carries the client's key share immediately, along with the cipher options and SNI. This is the key move that makes 1.3 one round trip — the client doesn't wait to be asked; it offers its half of the key exchange up front, guessing (correctly, almost always) which the server will accept.
- ServerHello picks the cipher and sends the server's key share back. At this instant both sides can independently derive the same shared symmetric key — the client has both shares, the server has both shares, but no eavesdropper ever saw the secret itself (that's the Diffie-Hellman magic). Everything after this in the flow is encrypted.
- Certificate and CertificateVerify deliver authenticity: the server sends its certificate chain, then signs a hash of the handshake so far with its private key. Only the real holder of the private key matching the certificate's public key can produce that signature — this is what proves the server is who the certificate claims.
- Finished on both sides is a checksum of the entire handshake, so any tampering with the earlier (unencrypted) hellos is caught before real data flows.
Count the trips: the client sends, the server responds, and the client can send its actual HTTP request in the very next message. One round trip of TLS setup, then data. If the server is 70ms away, that's ~70ms — on top of the ~70ms TCP handshake underneath it.
TLS 1.2 needed two. In the old flow the client's first message didn't carry a key share; the server had to respond, then the client sent its key material, then the server confirmed — a second full round trip before any data. So upgrading a server from TLS 1.2 to 1.3 literally removes ~70ms (one RTT) from every cold connection. That's not a micro-optimization; it's a round trip deleted from the critical path.
| TLS 1.2 | TLS 1.3 | |
|---|---|---|
| Handshake round trips | 2 RTT | 1 RTT |
| Client key share sent | after ServerHello | in ClientHello |
| Resumption | session IDs/tickets, still ~1 RTT | tickets, 0-RTT possible |
| Obsolete/weak ciphers | many still allowed | stripped from the spec |
What a certificate actually is
A certificate sounds mystical; it isn't. A certificate is a signed statement that says, essentially: "the public key inside this document belongs to api.hisaab.measdev.me, and I, the issuer, vouch for that." It bundles the server's public key, the domain name(s) it's valid for, an expiry date, and a digital signature from a Certificate Authority (CA).
That signature is the whole game. Anyone can generate a key pair and claim to be api.hisaab.measdev.me. What they can't do is get a trusted CA to sign a certificate for a domain they don't control — CAs only issue after verifying you own the domain (for Let's Encrypt, by making you place a specific file or DNS record only the owner could).
So when your browser gets the certificate, it doesn't trust it because it's pretty. It checks a chain of trust:
Root CA ──signs──► Intermediate CA ──signs──► api.hisaab.measdev.me
(in your OS/ (the CA's working (the "leaf" cert the
browser trust cert) server presented)
store, pre-installed)Your OS and browser ship with a trust store: a pre-installed list of a few hundred root CA public keys the vendors have vetted. The leaf certificate is signed by an intermediate, which chains up to one of those roots. Your browser verifies each signature in turn until it reaches a root it already trusts. Chain complete and valid, domain matches, not expired — padlock. Any broken link — the scary full-page warning. The trust is transitive: you trust the root, the root vouches for the intermediate, the intermediate vouches for the server.
SNI: why the server needs the name before HTTP exists
Here's a chicken-and-egg problem. One IP address (one server behind one nginx) can host many domains. During the handshake the server must send a certificate — but which one? The certificate is domain-specific, and the handshake happens before any HTTP, so the usual Host: header naming the site hasn't been sent yet (and couldn't be — it'd be inside encryption that isn't set up).
The fix is SNI (Server Name Indication): the client puts the target hostname in the ClientHello, in the clear, right at the start. Now the server knows which site you want and can present the matching certificate. Without SNI, virtual hosting over HTTPS would be impossible. The tradeoff: because SNI is sent before encryption exists, the hostname you're visiting is visible to the network even though everything after is encrypted. (Encrypted ClientHello is the evolving fix; classic SNI leaks the name.)
Resumption and 0-RTT: the fast path, with a catch
Doing the full handshake every time is wasteful when you talked to this server a minute ago. TLS 1.3 supports session resumption: after a successful handshake the server hands the client a session ticket (an encrypted blob of the session state). Next time, the client presents the ticket and both sides skip re-deriving everything from scratch — a cheaper handshake.
It goes further with 0-RTT ("zero round trip"): on resumption the client can send application data in its very first message, alongside the resumption attempt — no round-trip wait at all. Effectively free reconnects.
But 0-RTT has a real, sharp caveat you must respect:
Where the padlock lies
Now the part everyone gets wrong. The padlock proves confidentiality, integrity, and authenticity of the connection — an encrypted, untampered channel to the entity that legitimately controls the domain name you typed. That is all it proves.
It does not mean the site is honest, safe, or reputable. https://totally-legit-yourbank-login.com can have a perfect green padlock — because whoever registered that domain genuinely controls it and got a free certificate in thirty seconds. The padlock says "your bytes are going, privately and untampered, to the real owner of this domain." It says nothing about whether this domain is the one you meant, or whether its owner is a phisher. TLS authenticates the pipe, not the intent of whoever's on the other end. This is why phishing thrives on HTTPS: the lock is real, the encryption is real, and the site is still a scam. The padlock is a statement about the channel, never a character reference for the operator.
Go deeper
- The Illustrated TLS 1.3 Connection — Every single byte of a real 1.3 handshake, annotated in colour — the definitive "show me the actual wire" resource once the diagram above makes sense.
- High Performance Browser Networking — "Transport Layer Security (TLS)" — The performance-minded treatment: handshake round-trip costs, resumption, and OCSP, tying TLS latency back to the round-trip budget from earlier lessons.
- Cloudflare — "What happens in a TLS handshake?" — The clearest plain-English walkthrough of the handshake and the symmetric/asymmetric handoff; read it first if any step above went by too fast.
Check yourself
Answer out loud, as if an interviewer asked. If you hand-wave, reread that section.
- TLS uses both asymmetric and symmetric crypto. Which does the bulk data encryption and why, which is used only at the start and why, and what is the asymmetric part actually accomplishing given TLS 1.3 uses a Diffie-Hellman key exchange?
- What single design change lets TLS 1.3 complete its handshake in 1 RTT where TLS 1.2 needed 2? Point to the exact message and what it now carries.
- A certificate is "a signed statement." Signed by whom, binding what to what, and why can an attacker who fully controls their own server still not obtain a valid certificate for api.hisaab.measdev.me?
- Why does the client have to send the hostname in SNI in the clear at the very start of the handshake, rather than relying on the HTTP Host header like everything else? What does that leak?
- You enable 0-RTT to speed up reconnects and a POST that records a settlement occasionally executes twice. Explain the mechanism, and state the rule about which requests may travel as 0-RTT data.
- A phishing site shows a valid green padlock. Explain precisely what the padlock is and is not asserting, and why the lock being genuine does not contradict the site being a scam.