The Lock Icon Is a Whole Protocol
HTTPS is HTTP running inside TLS (Transport Layer Security). The lock icon isn’t magic — it’s the visible promise of three properties negotiated by a handshake:
- Confidentiality — no eavesdropper can read the traffic (symmetric encryption).
- Integrity — no one can tamper with a message in flight without detection (authenticated encryption).
- Authentication — the client can verify it is talking to the server it intends to, not an impostor (certificates).
Everything else — key exchange, certificates, cipher negotiation — exists to deliver those three guarantees cheaply and safely. This topic is the deep dive behind the overview in HTTP/HTTPS & REST APIs: how the handshake actually works, why your certificates expire, and the one tradeoff (0-RTT) that trades security for speed.
A Tiny Bit of Cryptography: Asymmetric vs Symmetric
Two kinds of crypto matter here:
- Symmetric encryption — one shared secret encrypts and decrypts. Fast (GCM/AES), but both sides need the same secret, and sharing it over an insecure channel is the problem.
- Asymmetric encryption / public-key crypto — a public key encrypts, a private key decrypts (or the private key signs, the public key verifies). Solves the secret-sharing problem but is hundreds of times slower.
TLS’s trick is a hybrid: use slow asymmetric crypto once, during the handshake, to derive a fast symmetric session key; then encrypt the entire session with that symmetric key. The one-time dance pays for the whole conversation.
Certificates and the Chain of Trust
Authentication needs an answer to “how do I know this public key really belongs to example.com?” A certificate is a signed statement: “This public key belongs to this domain.” But who signs it, and why should the client believe them?
The answer is a hierarchy of trust:
| Entity | Role |
|---|---|
| Root CA | A handful of globally trusted organizations (Let’s Encrypt, DigiCert, Sectigo…). Their keys are pre-installed in every browser/OS trust store. |
| Intermediate CA | Sits between root and leaf. Root CAs stay offline; intermediates sign the actual leaf certificates. |
| Leaf certificate | The server’s certificate — contains the domain (in the SAN field), the public key, expiry, and a signature from the intermediate. |
A client verifies the chain: leaf → intermediate → root, checking each signature against the parent’s public key, ending at a root it already trusts. If any link is broken, unknown, or expired, the browser shows the scary warning. The chain is also why “HTTPS broken” is almost always certificate trouble — a missing intermediate, an expired leaf, or a mismatched SAN.
The TLS 1.3 Handshake (1-RTT)
TLS 1.3 (the modern version) is dramatically simpler than 1.2: the handshake is one round trip, and the certificate exchange is encrypted — the studio at the end of this page steps through the exact messages: ClientHello + ECDHE key share → ServerHello + key derivation → encrypted certificates → Client Finished → application data, all in 1 RTT.
The key idea is ephemeral ECDHE key exchange:
- Client → Server:
ClientHello+ supported cipher suites + an ephemeral ECDHE key share. - Server → Client:
ServerHello+ its ECDHE key share + encryptedCertificate+CertificateVerify. - Both sides independently derive the same master secret from the two key shares (Diffie-Hellman) — then the same application traffic keys.
- Client sends
Finished; encrypted application data begins.
Two properties make this safe:
- Forward secrecy — the ECDHE keys are ephemeral (generated per-handshake and discarded). Even if an attacker later steals the server’s private key, they can’t decrypt recorded past traffic, because that traffic’s key never depended on the long-term key.
- Everything is encrypted from the start — even the certificate is hidden, so a passive observer can’t see which site you’re visiting (unlike TLS 1.2, where the certificate flew in plaintext).
0-RTT Session Resumption
Handshakes cost a round trip — noticeable on high-latency links. TLS 1.3 fixes this with session resumption: the server hands the client an encrypted Pre-Shared Key (PSK) ticket at the end of a session. On reconnect, the client sends ClientHello plus the first encrypted application data (0-RTT early data) in a single packet; the server replies immediately.
The 0-RTT studio in the visualizer shows the tradeoff: the first request is answered in 0.5 RTT total — but the early data is replayable. An attacker who captures the first packet can replay it to trigger the same request twice. That’s why 0-RTT is fine for idempotent GETs but dangerous for POSTs (payment, state changes). This is the classic security-vs-latency engineering decision.
mTLS
Normal TLS authenticates only the server. Mutual TLS (mTLS) adds the reverse: the client presents a certificate the server verifies. This is how service-to-service calls authenticate inside microservice meshes (Istio, Linkerd) and how many internal APIs gate access — it replaces “guess the API key” with “present a valid identity certificate.” The cost is key/cert lifecycle management for every service (see the operational pitfalls below).
Operational Pitfalls (This Is Where Production Breaks)
The handshake is elegant; the operations are where HTTPS dies. The operational rules of thumb:
- Certificates expire — that’s the design; renewal is the job.
Let's Encryptexists precisely because manual renewal fails. Automation (certbot, ACME) is non-negotiable. - A broken chain is the #1 cause of “HTTPS broken” — serving only the leaf without the intermediate leaves clients unable to complete the chain. Always bundle the chain.
- SANs must match the hostname — a cert for
example.comwon’t validatewww.example.comunless that name is in the SAN field. - Revocation is famously weak — CRLs and OCSP are inconsistently enforced; expect compromised-cert problems to be handled mostly via short lifetimes + automated rotation.
- SNI leaks the hostname — the client sends the server name in plaintext in
ClientHello(needed for virtual hosting); in TLS 1.3 the certificate itself is hidden, but SNI still is not. ECH (Encrypted Client Hello) is the fix, still rolling out.
Practice Trajectory
openssl s_client -connect example.com:443 -showcerts— dump the certificate chain, count the CAs, note expiry and SANs.curl -v https://example.com— read the TLS handshake lines and classify each phase.- Use
openssl s_client -tls1_2and-tls1_3— observe the handshake difference (1.2 sends the cert in plaintext; 1.3 hides it). echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates— see the exact expiry date.- If you have two services, try mTLS locally with
openssl reqto self-sign a CA + leaf pair.
When It’s the Right Tool
| Situation | Takeaway |
|---|---|
| Any public web service | HTTPS/TLS by default — no exceptions |
| High-latency or mobile traffic | 0-RTT resumption for idempotent early data |
| Service-to-service auth | mTLS over shared API keys |
| Long-lived sensitive data at rest | TLS protects transport only; data at rest needs encryption at rest |
| Debugging “HTTPS broken” | Chain order, SAN mismatch, and expiry — in that order |