Chapter 4 — TLS & HTTPS: The Encrypted Tunnel
TCP gives us a reliable connection. TLS makes it private and secure. Together they form HTTPS — the S stands for Secure.
The Simple Version (5-year-old)
Imagine you and Netflix want to pass notes in class, but you don't want the teacher (or anyone else) to read them.
Before passing the first note, you both do a secret handshake:
- You agree on a secret code (cipher).
- You use a magic trick so you both know the same code without ever writing it on paper (Diffie-Hellman key exchange — no key is ever transmitted).
- Netflix shows you their ID card (certificate) — signed by a trusted authority (like a government-issued ID) so you know it's really Netflix and not an imposter.
Now every note you pass is written in the secret code. Even if someone intercepts the note, they see scrambled gibberish.
That is TLS.
HTTP vs HTTPS
| HTTP | HTTPS | |
|---|---|---|
| Full name | HyperText Transfer Protocol | HTTP + TLS |
| Port | 80 | 443 |
| Encryption | None — plaintext | Negotiated authenticated encryption, commonly AES-GCM or ChaCha20-Poly1305 |
| Authentication | None — can't verify server identity | Certificate proves server identity |
| Integrity | None — data can be modified in transit | Authenticated encryption detects tampering |
| Visible to ISP | Everything (URLs, cookies, content) | Destination IP, timing, size, and usually hostname via SNI unless ECH is used |
What TLS Provides
TLS gives three security properties:
- Confidentiality — data is encrypted. Nobody can read it in transit.
- Integrity — TLS records are authenticated, so tampering is detected.
- Authentication — the certificate helps prove you're talking to the holder of the private key for that hostname, chained to a trusted CA.
TLS 1.3 Handshake — Step by Step
TLS 1.3 (standardized in RFC 8446) usually completes in 1 Round Trip Time (RTT) for a fresh connection — faster than a typical TLS 1.2 full handshake.
Client (browser) Server (Netflix edge)
│ │
│───── ClientHello ───────────────────────►│
│ • TLS version: 1.3 │
│ • Supported cipher suites: │
│ TLS_AES_256_GCM_SHA384 │
│ TLS_CHACHA20_POLY1305_SHA256 │
│ • Client's DH key share (public) │
│ • SNI: "www.netflix.com" │ ← Which hostname?
│ • ALPN: ["h2", "http/1.1"] │ ← Which HTTP version?
│ • Session ticket (if resuming) │
│ │
│◄──── ServerHello + {encrypted} ─────────│
│ • Selected cipher: AES_256_GCM_SHA384 │
│ • Server's DH key share (public) │
│ ┌── encrypted from here ─────────────┐ │
│ │ • Certificate chain │ │
│ │ (netflix.com cert + DigiCert CA) │ │
│ │ • CertificateVerify │ │
│ │ (proves server owns private key) │ │
│ │ • Finished │ │
│ │ (authenticator over handshake) │ │
│ └────────────────────────────────────┘ │
│ │
│ [Browser verifies certificate] │
│ [Both sides independently derive │
│ the same session keys via ECDHE] │
│ │
│───── Finished (encrypted) ──────────────►│
│ Authenticator over entire handshake │
│ │
│ [Encrypted channel established] │
│ HTTP/2 request can now be sent │
Total cost: 1 RTT for TLS handshake + 1 RTT for TCP handshake = 2 RTTs before first byte of HTTP data.
Key Exchange — The Magic of ECDHE
The most important question in TLS: how do two parties agree on a secret key without ever sending that key over the network?
If an attacker records your entire TLS handshake, they must not be able to decrypt it — even if they later steal the server's private key.
This property is called Forward Secrecy.
Diffie-Hellman Key Exchange (Simple Analogy)
Imagine you and Netflix both have a common base color (public — everyone knows it). You each mix in your own secret color privately. You exchange your mixed colors. Each of you then mixes the other's mixed color with your own secret. You both end up with the same final color — but nobody watching the exchange ever sees either secret color.
ECDHE — Elliptic Curve Diffie-Hellman Ephemeral
1. Both agree on a public elliptic curve (e.g., X25519) — public knowledge.
2. Client generates a random private key (a secret number).
Client computes: public_key_client = private_key_client × generator_point
3. Server generates a random private key.
Server computes: public_key_server = private_key_server × generator_point
4. They exchange public keys (visible to everyone).
5. Client computes: shared_secret = private_key_client × public_key_server
Server computes: shared_secret = private_key_server × public_key_client
These are mathematically equal! Both get the same shared_secret.
But an eavesdropper who sees both public keys cannot compute shared_secret
(Elliptic Curve Discrete Logarithm Problem — computationally infeasible).
6. shared_secret → key derivation → session keys for encryption
Ephemeral means a new key pair is generated for every connection. Even if you crack today's session key, you cannot decrypt past or future sessions. This is forward secrecy.
TLS Certificate — Proving Identity
The server's certificate answers: "Is this really netflix.com?"
A certificate is a digital document containing:
- Subject:
www.netflix.com - Issuer:
DigiCert SHA2 Secure Server CA(the Certificate Authority) - Public Key: Netflix's public key
- Validity Period: Not Before / Not After
- Signature: DigiCert's digital signature over all the above
- SANs (Subject Alternative Names): Other hostnames this cert is valid for (
*.netflix.com)
Certificate Chain of Trust
No single authority is universally trusted. Instead, there is a hierarchy:
Root CA (DigiCert Global Root CA)
│ Self-signed. Pre-installed in your OS/browser trust store.
│ Signs the Intermediate CA certificate.
│
└──► Intermediate CA (DigiCert SHA2 Secure Server CA)
│ Signed by Root CA.
│ Signs Netflix's certificate.
│
└──► End-Entity Certificate (www.netflix.com)
Subject: www.netflix.com
Issuer: DigiCert SHA2 Secure Server CA
Signed by Intermediate CA.
Why three levels? Security. Root CA private keys are usually kept offline or under very strict controls, while intermediate CAs handle day-to-day issuance. If an intermediate CA is compromised, it can be revoked without replacing the root trust anchor.
Certificate Validation Steps
When the browser receives Netflix's certificate:
1. Is the certificate's Subject (or SAN) = "www.netflix.com"?
If NO → error: certificate name mismatch
2. Is the current date between the cert's Not Before and Not After?
If NO → error: certificate expired
3. Is the Intermediate CA's certificate valid? (recursively up the chain)
Is the Root CA in our trust store?
If NO → error: untrusted certificate authority
4. Verify the signature: DigiCert's signature on the cert is valid?
Use DigiCert's public key to verify.
If NO → error: invalid signature
5. Is revocation information available and enforced by this client?
If the browser has hard-fail revocation data or a required staple says
revoked → error. In many ordinary OCSP failures, browsers historically
soft-fail to avoid breaking the web.
6. CAA is normally checked by the CA before issuance, not by the browser on
every connection. It prevents the wrong CA from issuing the certificate in
the first place.
All checks pass → certificate trusted ✓
OCSP — Online Certificate Status Protocol
OCSP lets browsers check in real-time if a certificate has been revoked (e.g., Netflix's private key was stolen).
Problem: Browser must make a separate network request to DigiCert's OCSP server for every HTTPS connection — adds latency, privacy risk (DigiCert sees who you visit).
OCSP Stapling (solution): Netflix's server fetches the OCSP response from DigiCert itself (periodically), then staples (includes) it in the TLS handshake. Browser gets proof of validity without making a separate request.
SNI — Server Name Indication
A single server IP may host thousands of websites (virtual hosting). Before TLS is established, the server doesn't know which certificate to present.
SNI solves this: the client includes the hostname (www.netflix.com) in the ClientHello — before encryption starts — so the server can select the right certificate.
ClientHello includes:
SNI: "www.netflix.com"
Server selects:
Certificate for www.netflix.com ✓ (not youtube.com, not google.com)
Privacy implication: SNI is sent in plaintext. Your ISP and anyone on the path can see which hostname you're connecting to (even though they can't see the content). Encrypted Client Hello (ECH) is a newer standard that encrypts the SNI.
ALPN — Application Layer Protocol Negotiation
In the same ClientHello, the browser advertises which HTTP versions it supports:
ALPN: ["h2", "http/1.1"]
Server responds with its selection:
ALPN: "h2" → use HTTP/2 over TLS/TCP
ALPN: "h3" → use HTTP/3 inside QUIC's TLS 1.3 handshake
For HTTP/1.1 and HTTP/2 over TCP, ALPN avoids a separate upgrade roundtrip
after TLS is established. HTTP/3 uses QUIC, so browsers usually discover it via
Alt-Svc or HTTPS DNS records and then negotiate h3 inside QUIC's TLS 1.3
handshake.
SSL Termination, Bridging, and Passthrough
There are three ways to handle TLS at the edge:
1. TLS termination (often called "SSL termination")
Client ──[HTTPS/TLS]──► Edge (Nginx/Envoy) ──[HTTP or internal TLS]──► Origin
▲
TLS terminates here.
Edge decrypts, reads HTTP, can cache/rate-limit/inspect.
Forwards plaintext or re-encrypts to origin.
Pros: Edge can inspect content (cache, rate limit, auth, WAF), lower origin CPU load. Cons: Traffic between edge and origin is decrypted — must trust internal network or use internal TLS.
2. SSL Bridging / Re-encryption
Client ──[TLS]──► Edge ──[NEW TLS connection]──► Origin
Edge terminates the client TLS session and creates a new TLS session to the origin. Edge can still inspect content. Two separate encrypted channels.
3. SSL Passthrough
Client ──[TLS]──────────────────────────────► Origin
Edge only routes TCP stream.
Never decrypts. Cannot inspect.
Pros: Maximum privacy — even the edge doesn't see the content. Cons: Cannot cache, cannot rate limit at HTTP level, cannot do WAF.
Session Resumption — Not Starting from Scratch
TLS handshakes are expensive (crypto operations, certificate parsing). For returning users, TLS 1.3 allows session resumption:
TLS 1.3 Pre-Shared Key (PSK) — 0-RTT
First visit:
Full TLS 1.3 handshake (1 RTT)
Server sends a "session ticket" — an encrypted blob the client stores.
Returning visit:
ClientHello + session ticket + [early data — the HTTP request!]
↓
Server decrypts ticket, resumes session, processes early data immediately
→ HTTP response starts before TLS handshake even completes!
→ 0 RTT for returning users
Security trade-off of 0-RTT: Early data is replay-vulnerable. An attacker who captures your ClientHello + early data can resend it later. For this reason, 0-RTT is only used for idempotent requests (GET requests that don't change state). Never for POST/payments.
TLS 1.3 vs TLS 1.2 — Why the Upgrade Matters
| Feature | TLS 1.2 | TLS 1.3 |
|---|---|---|
| Handshake RTTs | 2 RTTs | 1 RTT (0 RTT on resume) |
| Cipher suites | Many (some weak) | 5 (all strong) |
| Forward secrecy | Optional | Mandatory |
| RSA key exchange | Allowed (no forward secrecy) | Removed |
| Certificate in handshake | Plaintext | Encrypted |
| Downgrade attacks | Possible | Prevented (via Finished message) |
| Performance | Slower | Faster |
TLS 1.0 and 1.1 are deprecated (2020). TLS 1.2 is still widely used but being phased out. TLS 1.3 is the target.
What an Attacker Can and Cannot See
With HTTPS correctly implemented:
| Information | Visible to attacker? |
|---|---|
| Destination IP address | YES — IP routing requires this |
| Destination hostname (SNI) | YES — sent in plaintext ClientHello (ECH fixes this) |
| HTTP method (GET/POST) | NO — inside TLS |
| URL path and query string | NO — inside TLS |
| Request headers | NO — inside TLS |
| Cookies | NO — inside TLS |
| Response body | NO — inside TLS |
| Response headers | NO — inside TLS |
| Timing / packet sizes | YES — traffic analysis possible |
mTLS — Mutual TLS
Standard TLS: only the server proves its identity (via certificate). The client is anonymous.
mTLS (Mutual TLS): Both the server AND the client present certificates. Both authenticate each other.
Standard TLS:
Server presents cert → Browser verifies → Trust established
mTLS:
Server presents cert → Client verifies
Client presents cert → Server verifies
→ Both sides authenticated
Used for:
- Service-to-service authentication (microservices inside Netflix's cluster authenticate each other)
- Zero-trust networks (no implicit trust even inside the datacenter)
- API clients that need strong authentication beyond passwords
Common TLS Attacks
| Attack | What Happens | Mitigation |
|---|---|---|
| MITM (Man-in-the-Middle) | Attacker intercepts and impersonates server | Certificate validation, HSTS |
| Downgrade Attack | Attacker forces negotiation to older, weaker TLS | TLS 1.3 Finished message detects tampering, HSTS |
| BEAST | Exploits TLS 1.0 CBC mode flaw | TLS 1.2+, AES-GCM |
| POODLE | SSLv3 CBC padding oracle | Disable SSLv3 |
| HEARTBLEED | OpenSSL bug leaking server memory (including private keys) | Patched OpenSSL, certificate rotation |
| Certificate Misissuance | CA issues cert for wrong domain | CAA records, Certificate Transparency |
| Weak cipher suites | Attacker forces use of weak encryption | TLS 1.3 eliminates weak ciphers |
Certificate Transparency (CT)
A public, append-only log of every TLS certificate ever issued. Browsers require certificates to be logged in CT logs. If a CA mistakenly issues netflix.com to an attacker, Netflix's monitoring will detect it within minutes.
Across the series
- Inspect any server's TLS from code: the
tlsinspectlab (TCP/IP guide, Chapter 29) prints version, cipher, ALPN, and the chain, and names the four classic certificate failures (expired, unknown authority, name mismatch, SNI refused). - Rotate certificates without downtime with
tls.Config.GetCertificate: TCP/IP guide, Chapter 56. Inventory and expiry scanning: this guide's Chapter 16. - mTLS in Go: the Go guide's mTLS chapter builds a private CA and client-certificate authentication end to end. The Go plan's Week 6 adds a PKI generator and identity extraction.
- Session resumption, measured: in testing for the TCP/IP guide, a Go client resumed a TLS 1.3 session only after it had read from the first connection, because TLS 1.3 servers send the session ticket after the handshake.
Key Takeaways
- HTTPS = HTTP + TLS. TLS provides encryption, integrity, and authentication.
- A fresh TLS 1.3 handshake usually costs 1 RTT. Keys are derived via ECDHE — the shared session key is not transmitted.
- Certificates prove server identity through a chain of trust from Root CA → Intermediate CA → End-entity cert.
- SNI tells the server which certificate to use when multiple sites share an IP.
- SSL Termination at the edge is standard — edge decrypts, inspects, and forwards.
- 0-RTT resumption is fast but replay-vulnerable — safe for GET, not POST.
- mTLS authenticates both sides — used for internal service-to-service communication.
- Certificate Transparency makes misissued certificates publicly visible.