HTTPS / TLS Fundamentals
A Complete 12-Chapter Course
Table of Contents
- Why HTTPS? HTTP's Problems
- Cryptography Building Blocks
- Public-Key Crypto & Key Exchange
- Certificates & the X.509 Format
- Certificate Authorities & the Chain of Trust
- The TLS 1.2 Handshake
- TLS 1.3 β What Changed
- Cipher Suites & Protocol Versions
- Getting a Certificate β Let's Encrypt & ACME
- Configuring HTTPS on a Server
- Common Problems & Attacks
- Beyond the Basics
Why HTTPS? HTTP's Problems
Before learning how HTTPS works, it's worth being precise about what problem it solves. HTTPS is just HTTP carried over TLS (Transport Layer Security) β the application protocol is unchanged; what changes is that everything travels through an encrypted, authenticated channel instead of as open text. This chapter sets up the threat model the rest of the course answers.
Plain HTTP Travels in the Clear
An HTTP request is plain text sent over TCP. Every device between your computer and the server β your router, your ISP, every network hop, the coffee-shop Wi-Fi access point β handles those bytes, and with plain HTTP they can read every one of them. A login request looks literally like this on the wire:
There is no encryption, no signature, no proof of who sent it or who received it. Anyone positioned on the path sees the URL, the headers, the cookies, and the body β including that password in the clear. This is the default behaviour of HTTP, and it is the baseline HTTPS exists to fix.
Three Things Can Go Wrong
The weaknesses of plain HTTP fall into three distinct categories. Keeping them separate matters, because HTTPS addresses each one with a different mechanism (which later chapters cover):
| Threat | What the attacker does | Example |
|---|---|---|
| Eavesdropping | Passively reads traffic as it passes | Capturing a password or cookie on open Wi-Fi |
| Tampering | Actively modifies traffic in transit | Injecting ads/malware into a page; altering a bank transfer amount |
| Impersonation | Pretends to be the server (or client) | A fake "example.com" capturing your credentials |
When all three are combined by an attacker sitting between the two parties β reading, modifying, and impersonating at once β it's called a man-in-the-middle (MITM) attack. The MITM is the central adversary the whole TLS design is built to defeat.
The Three Guarantees HTTPS Provides
Each threat is answered by a corresponding guarantee. These three words are the spine of the entire course β every mechanism you'll learn exists to deliver one of them:
Notice the mapping is one-to-one: confidentiality β eavesdropping, integrity β tampering, authentication β impersonation. A common beginner mistake is to think "HTTPS = encryption" and stop there β but encryption alone (confidentiality) would still let you have a perfectly private conversation with an impostor. Authentication is what makes the encryption meaningful, by guaranteeing who you've established the private channel with.
What HTTPS Does and Doesn't Protect
A precise mental model also means knowing the limits. HTTPS protects data in transit between the two endpoints β and only that:
- Protected: the request/response bodies, headers, cookies, and the specific path & query string β all unreadable and unmodifiable to anyone on the network path.
- Still visible to the network: the domain name you're connecting to (via DNS and the TLS handshake's SNI field) and the rough size/timing of traffic. Observers know you visited
example.com, just not what you did there. - Not HTTPS's job at all: security at the endpoints β a hacked server, malware on your machine, a phishing site with its own valid certificate, or a weak password. HTTPS secures the pipe, not what's at either end of it.
examp1e.com can obtain a perfectly legitimate certificate and show a padlock. HTTPS guarantees you're talking privately to whoever owns that exact domain; it does not guarantee that owner is honest. Don't read the padlock as a safety endorsement of the site's content.
The Cost Is Now Negligible
Historically HTTPS was seen as slow and expensive (CPU cost, paid certificates), which is why plain HTTP lingered. That's no longer true: modern CPUs handle TLS with minimal overhead, TLS 1.3 cut the handshake cost dramatically (Chapter 7), and certificates are now free and automatable via Let's Encrypt (Chapter 9). Today HTTPS is the default expectation β browsers mark plain HTTP pages as "Not Secure," and many web features (HTTP/2, service workers, geolocation) simply refuse to run without it. There's no longer a real argument for plaintext HTTP on the public web.
Hands-On Exercises
Using curl's verbose mode, compare a plain HTTP request and an HTTPS request to the same kind of endpoint, and identify in the output where TLS is negotiated for the HTTPS one. (Hint: curl -v http://example.com vs curl -v https://example.com.)
Open your browser's DevTools Network tab, load any HTTPS site, click a request, and locate (a) the protocol/security info confirming the connection is encrypted and (b) the request headers β noting that you can read them locally even though the network cannot. Then map what you see to the three guarantees.
π View solutionFor each of these scenarios, name which of the three guarantees (confidentiality / integrity / authentication) is the one being violated: (a) an ISP injects an ad banner into a web page; (b) someone on your Wi-Fi reads your session cookie; (c) you connect to a rogue access point posing as your bank's site. Write a one-line justification for each.
π View solutionChapter 1 Quick Reference
- HTTPS = HTTP over TLS β same HTTP, carried through an encrypted & authenticated channel
- Plain HTTP is plaintext: every hop can read URLs, headers, cookies, and bodies
- Three threats: eavesdropping (read), tampering (modify), impersonation (pretend to be the server)
- A man-in-the-middle (MITM) combines all three β the core adversary TLS defeats
- Three guarantees: confidentiality (encryption), integrity (tamper-detection), authentication (certificates)
- HTTPS β "encryption only" β without authentication you'd just have a private chat with an impostor
- SSL is the obsolete ancestor of TLS; "SSL certificate" colloquially means a TLS certificate
- Protects data in transit, not the endpoints; the padlock means "private," not "trustworthy"
- Next chapter: the cryptographic building blocks β symmetric vs asymmetric encryption, hashing, MACs
Cryptography Building Blocks
TLS doesn't invent its own cryptography β it assembles a handful of well-studied primitives into a protocol. This chapter introduces those primitives in plain terms, mapping each to the guarantee it provides (Chapter 1). You don't need the maths; you need to know what each tool does, what key it uses, and what it can't do alone.
Symmetric Encryption β One Shared Key
Symmetric encryption uses a single secret key to both encrypt and decrypt. The same key locks and unlocks β like a physical door key that both parties hold a copy of. The dominant algorithm is AES (Advanced Encryption Standard).
Symmetric encryption is fast β easily fast enough to encrypt every byte of a web page or video stream β and it delivers confidentiality. Its one hard problem: both sides must already share the same secret key. How do two strangers on the internet agree on a shared secret without an eavesdropper learning it? They can't, with symmetric crypto alone. That gap is exactly what asymmetric crypto solves.
Asymmetric Encryption β A Key Pair
Asymmetric (or public-key) encryption uses a pair of mathematically linked keys: a public key that can be shared with anyone, and a private key kept secret by its owner. What one key locks, only the other can unlock. The common algorithms are RSA and the elliptic-curve family (ECDH/ECDSA).
| Use the⦠| To⦠| Giving you |
|---|---|---|
| recipient's PUBLIC key to encrypt | send a secret only the holder of the matching private key can read | Confidentiality (anyone can encrypt to you) |
| your own PRIVATE key to sign | prove a message came from you (only you have that key) | Authentication (a digital signature) |
This neatly solves the "strangers sharing a secret" problem: you can hand your public key to the whole world, and anyone can use it to send you something only your private key can open. The catch is that asymmetric operations are slow and computationally heavy β far too slow to encrypt an entire data stream.
Hashing β A One-Way Fingerprint
A cryptographic hash function (e.g. SHA-256) takes any input and produces a fixed-size "fingerprint" β the digest. It has three defining properties:
- Deterministic: the same input always yields the same digest.
- One-way: you cannot reverse a digest back into the original input.
- Collision-resistant & avalanche: two different inputs (practically) never share a digest, and changing a single bit of input scrambles the entire output.
Hashing on its own provides integrity checking: if you know the expected digest of some data, you can re-hash what you received and confirm it wasn't altered. But note what hashing alone does not give you β see the next section.
MACs β Integrity WITH a Key
A MAC (Message Authentication Code) is like a hash, but it also folds in a secret key. Only someone holding the key can produce a valid MAC for a message, and only someone with the key can verify it. The common construction is HMAC (e.g. HMAC-SHA256).
Because forging a valid tag requires the secret key, a MAC delivers integrity and a form of authentication at once: it proves the message wasn't altered and that it came from someone who shares the key. This is how TLS protects each record of application data after the handshake β using the symmetric key it just negotiated.
TLS_AES_256_GCM_SHA384 in Chapter 8 β the "GCM" part is the AEAD mode. Conceptually it's still "symmetric encryption + a MAC," just fused into one safer primitive.
Putting the Primitives Against the Guarantees
| Primitive | Key model | Speed | Provides |
|---|---|---|---|
| Symmetric (AES) | one shared secret key | fast | Confidentiality |
| Asymmetric (RSA, ECDH) | public + private key pair | slow | Key exchange & Authentication |
| Hash (SHA-256) | no key | fast | Integrity (keyless) |
| MAC / HMAC | one shared secret key | fast | Integrity + sender authenticity |
| AEAD (AES-GCM) | one shared secret key | fast | Confidentiality + Integrity together |
No single primitive provides all three guarantees β TLS is essentially the recipe for combining them: asymmetric crypto to establish a shared symmetric key and to authenticate the server (via certificates, Chapter 4), then AEAD symmetric crypto to protect every byte of data with confidentiality and integrity. The next chapter zooms in on the asymmetric half: how two parties actually agree on that shared key.
Hands-On Exercises
Use sha256sum (or openssl dgst -sha256) to hash a short string, then hash it again after changing a single character. Confirm the digest length is identical but the value is completely different (the avalanche effect), and explain why this property matters for integrity checking.
Using openssl, time a symmetric operation vs an asymmetric one to feel the speed gap: generate an RSA key and do a public-key operation, and separately encrypt a chunk of data with AES. Then explain in your own words why TLS uses the slow asymmetric step only to set up the fast symmetric one.
π View solutionFor each item, name the primitive that fits and the guarantee it provides: (a) encrypting a 4 GB video stream efficiently; (b) letting strangers send you a secret with nothing pre-shared; (c) proving a downloaded file wasn't corrupted, given a trusted digest; (d) proving a message both is intact and came from someone sharing your key.
π View solutionChapter 2 Quick Reference
- Symmetric (AES) β one shared key encrypts & decrypts; fast; gives confidentiality; problem = sharing the key
- Asymmetric (RSA, ECDH) β public + private key pair; slow; solves key sharing & enables signatures/authentication
- Hybrid model β asymmetric to agree a fresh symmetric key, then symmetric for the bulk data (the core TLS idea)
- Hash (SHA-256) β keyless one-way fingerprint; deterministic, irreversible, avalanche; gives keyless integrity
- A plain hash can't prove who sent data β an attacker recomputes it; you need a key
- MAC / HMAC β hash + secret key; integrity AND sender authenticity
- AEAD (AES-GCM, ChaCha20-Poly1305) β fuses encryption + integrity in one step; used by modern TLS
- Next chapter: public-key crypto & key exchange β RSA vs DiffieβHellman, and forward secrecy
Public-Key Crypto & Key Exchange
Chapter 2 established the hybrid model: use asymmetric crypto to agree on a shared symmetric key, then switch to fast symmetric encryption. This chapter answers the obvious follow-up β how exactly do the two parties agree on that key over a network an attacker is watching? There are two historical approaches, and the difference between them turns out to matter enormously for security.
Approach 1: RSA Key Transport (the old way)
The original TLS method used RSA key transport. The logic is simple:
- The server has an RSA key pair; its public key is in its certificate (Chapter 4).
- The client invents a random secret (the "pre-master secret"), encrypts it with the server's public key, and sends it.
- Only the server's private key can decrypt it, so now both sides share that secret β from which the symmetric key is derived.
It works and it's easy to picture: the client effectively puts the secret in a box only the server can open. But it has a serious, subtle weakness that took the industry years to fully act on.
Approach 2: DiffieβHellman Key Exchange (the modern way)
DiffieβHellman (DH) solves the problem differently β and almost magically. It lets two parties derive a shared secret by exchanging only public values, such that an eavesdropper who sees everything sent still cannot compute the secret. The classic intuition is mixing paint:
The shared secret (brown) is never transmitted β each side computes it locally by combining their own private value with the other's public value. The "un-mixing is hard" property is, in real DH, the difficulty of certain mathematical problems (discrete logarithms). Critically, the secret was never put in a box tied to a long-lived key β it emerged from values that can be thrown away after the session.
Ephemeral DiffieβHellman = Forward Secrecy
The security payoff comes when the DH private values are ephemeral β freshly generated for each session and discarded immediately afterward. This is signalled by an E in cipher names: DHE (ephemeral DH) and ECDHE (the elliptic-curve, faster variant used almost universally today).
But Wait β Where Does Authentication Fit?
Plain DiffieβHellman has a gap: it establishes a shared secret with somebody, but it doesn't prove who. An active man-in-the-middle could run separate DH exchanges with each side and sit in the middle. DH alone gives confidentiality, not authentication β exactly the Chapter 1 warning that encryption without authentication is a private chat with a possible impostor.
TLS closes the gap by combining DH with a signature: the server signs its DH public value with the long-term private key from its certificate. So the two asymmetric tools play distinct roles, and it's worth keeping them separate in your mind:
| Asymmetric role | Tool | Provides | Key used |
|---|---|---|---|
| Key agreement | (EC)DHE | a shared secret + forward secrecy | ephemeral, per-session, discarded |
| Authentication | signature (RSA or ECDSA) | proof of server identity | long-term key from the certificate |
This is a key clarification: in modern TLS the certificate's long-term key is used to sign (authenticate), not to encrypt the session secret. The session secret comes from ephemeral DH. That separation is precisely what delivers both authentication and forward secrecy at once β the old RSA-transport method conflated the two into one key and lost forward secrecy as a result.
RSA Transport vs Ephemeral DH β Side by Side
| RSA key transport (legacy) | Ephemeral DH β (EC)DHE (modern) | |
|---|---|---|
| How secret is shared | client encrypts it to server's public key | both derive it from exchanged public values |
| Long-term key's job | decrypts the session secret | only signs (authenticates) |
| Forward secrecy | No β key theft decrypts all past traffic | Yes β past sessions stay safe |
| Status | removed in TLS 1.3 | the only option in TLS 1.3 |
The progression is the whole point of this chapter: TLS 1.2 supported both, and TLS 1.3 (Chapter 7) dropped RSA key transport altogether, making forward secrecy mandatory. Every modern HTTPS connection you make uses ephemeral elliptic-curve DiffieβHellman (ECDHE) for key agreement, authenticated by a certificate signature. The next chapter examines that certificate itself.
Hands-On Exercises
Connect to a real site with openssl s_client -connect example.com:443 and find the line reporting the negotiated key exchange / cipher (look for "Server Temp Key" and the cipher name). Identify whether ECDHE is in use, and explain what the "E" guarantees.
Walk through the paint-mixing analogy with actual small numbers using the real DH formula (pick a small prime p and base g, choose two private exponents, compute the public values and the shared secret both ways). Confirm both sides reach the same secret, and state what an eavesdropper would and wouldn't know.
π View solutionExplain the "harvest now, decrypt later" attack in one paragraph, then state precisely why RSA key transport is vulnerable to it but ephemeral ECDHE is not. Be specific about which key is stolen and what it can (or can't) unlock in each case.
π View solutionChapter 3 Quick Reference
- Key exchange = how two parties agree on the shared symmetric key over a watched network
- RSA key transport (legacy) β client encrypts the secret to the server's public key; simple but NO forward secrecy
- DiffieβHellman β both derive a shared secret from exchanged PUBLIC values; the secret is never transmitted
- Ephemeral DH (DHE / ECDHE) β fresh per-session values, discarded after = forward secrecy
- Forward secrecy β stealing the long-term key later can't decrypt past recorded sessions
- Plain DH gives confidentiality but not authentication β TLS signs the DH value with the certificate key
- Modern split: (EC)DHE agrees the key (ephemeral), the certificate key only signs/authenticates
- TLS 1.3 removed RSA key transport β ECDHE forward secrecy is now mandatory
- Next chapter: certificates & the X.509 format β what proves the server's identity
Certificates & the X.509 Format
Chapter 3 left one piece dangling: the server authenticates itself by signing the handshake with its long-term private key β but how does the client know that key belongs to the right server? The answer is the certificate: a signed document binding a public key to an identity (a domain name). This chapter opens one up and names every part.
What Problem a Certificate Solves
A raw public key is just a number β it carries no identity. If a server simply handed you a public key, an impostor could hand you their public key just as easily; you'd have no way to tell which one truly belongs to example.com. A certificate fixes this by binding a public key to a name and having a trusted third party (a Certificate Authority, Chapter 5) vouch for that binding with a signature.
X.509 β The Standard Certificate Format
TLS certificates follow the X.509 standard, which defines the fields a certificate contains. Here are the ones that matter, as you'll see them in real output:
| Field | What it holds | Why it matters |
|---|---|---|
| Subject | who the cert identifies β incl. Common Name (CN) | the identity being vouched for |
| Subject Alternative Name (SAN) | the list of domain names the cert is valid for | this is what browsers actually check today |
| Issuer | which CA issued & signed this cert | the next link up the trust chain (Ch. 5) |
| Validity (Not Before / Not After) | the date range the cert is valid | expired or not-yet-valid = rejected |
| Public Key | the server's public key + algorithm (RSA/EC) | the key being bound to the identity |
| Signature | the issuer's signature over all the above | makes the cert tamper-evident |
| Serial / Extensions | unique ID, key-usage flags, CRL/OCSP URLs | revocation & usage constraints (Ch. 10β11) |
Reading a Real Certificate
You can fetch and decode any site's certificate with openssl. The -text option prints the X.509 fields in human-readable form:
Every concept so far appears here: the Subject identity, the Public Key (the one used in Chapter 3's signature), the Issuer (the CA that vouched for it), the Validity window, and the SAN list of covered domains.
*.example.com) in one cert, which CN couldn't. When you check "does this cert match the site I'm visiting?", you're checking the SAN list.
How the Signature Makes It Tamper-Proof
The certificate's integrity rests on the primitives from Chapter 2. The CA computes a hash of all the certificate's data fields, then signs that hash with the CA's private key. Anyone can verify it using the CA's public key:
Because only the CA's private key can produce a signature that verifies against its public key, nobody can alter a single field (say, swap in their own public key or change the domain) without invalidating the signature. This is the same hash-then-sign pattern from Chapter 2, applied to the certificate itself β and it's why a certificate can be transmitted in the clear yet still be trustworthy.
PEM vs DER β Encodings, Not Different Certificates
Certificates come in two file encodings, which trip up beginners because they look totally different but hold the same data:
| Encoding | Looks like | Typical extensions |
|---|---|---|
| PEM | Base64 text between -----BEGIN CERTIFICATE----- markers | .pem .crt .cer |
| DER | raw binary (not human-readable) | .der .cer |
PEM is the common one on Linux servers (and what you paste into config files); DER is binary. They're interconvertible with openssl x509 -inform/-outform, and -text decodes either into the readable field listing above. Don't mistake the encoding for the content β a .pem and a .der of the same cert are the same certificate.
Hands-On Exercises
Fetch a real site's certificate with openssl and print it with x509 -text -noout. Locate and write down its Subject, Issuer, Validity dates, public key algorithm/size, and the Subject Alternative Name list.
Use targeted openssl flags to extract just specific fields: -subject, -issuer, -dates, and -ext subjectAltName. Then explain why a browser visiting www.example.com checks the SAN list rather than the Common Name.
Inspect a certificate in your browser's certificate viewer (click the padlock) and find the same fields. Then reason about three rejection scenarios: an expired cert, a cert whose SAN doesn't include the visited domain, and a cert with one data field altered after signing β state which check fails in each.
π View solutionChapter 4 Quick Reference
- A certificate binds a public key to an identity (domain), vouched for by a CA's signature
- It solves the problem that a raw public key carries no identity β an impostor's key looks the same
- X.509 is the format; key fields: Subject, SAN, Issuer, Validity, Public Key, Signature
- SAN (Subject Alternative Name) β the domain list browsers actually check; CN is ignored for matching
- Read one with
openssl x509 -text -noout(decodes both PEM and DER) - The CA hashes then signs the cert data β altering any field breaks the signature (tamper-evident)
- PEM (Base64 text) vs DER (binary) are encodings of the same certificate
- Validity windows are short (~90 days) by design β automation (ACME) makes that practical
- Next chapter: Certificate Authorities & the chain of trust β who signs the signers
Certificate Authorities & the Chain of Trust
Chapter 4 said a certificate is trustworthy because a Certificate Authority signed it. But that just moves the question: why trust the CA? This chapter answers it by following the chain all the way up to its anchor β and explains the one thing your device actually has to trust to begin with.
The Bootstrapping Problem
A certificate's signature is only as good as your trust in whoever signed it. If you have to verify the signer with another certificate, and that one with another, the chain has to stop somewhere β otherwise it's turtles all the way down. The chain stops at a root certificate that your device trusts inherently, not because something else vouched for it.
Three Tiers: Root, Intermediate, Leaf
Real-world certificates form a chain of (usually) three levels. Each certificate is signed by the one above it:
| Tier | Signed by | Role |
|---|---|---|
| Root CA | itself (self-signed) | the trust anchor; lives in the trust store; key guarded offline |
| Intermediate CA | the root (or another intermediate) | issues leaf certs daily, shielding the root key from exposure |
| Leaf / end-entity | an intermediate | the actual certificate for a website's domain |
How Verification Walks the Chain
When your browser receives the server's certificate, it builds and verifies the chain link by link. The server is expected to send its leaf cert plus the intermediate(s) β but not the root, which the client already has:
At each step the browser also re-checks everything from Chapter 4: validity dates, that the issuer's certificate is allowed to act as a CA, and (at the leaf) that the SAN matches the site. The chain is only trusted if every link verifies and it terminates at a root in the trust store.
What a CA Actually Verifies (and Doesn't)
Before issuing a leaf certificate, a CA validates the request β but how much it checks defines the validation level:
| Level | What the CA verifies | Used for |
|---|---|---|
| DV (Domain Validation) | only that you control the domain (Chapter 9) | the vast majority of sites; free via Let's Encrypt |
| OV (Organization Validation) | domain control + the organization's real existence | business sites wanting vetted identity |
| EV (Extended Validation) | a rigorous legal-identity check | once gave the "green bar"; now visually de-emphasized |
Crucially, even the strictest level only verifies identity, never honesty. A DV certificate proves "the holder controls this domain" β nothing about whether the site is safe. This is the Chapter 1 point made concrete: the chain of trust authenticates who you're talking to, not whether they deserve your trust.
yourbank.com to someone who doesn't control that domain. It is not an endorsement of any site the CA issues to. This is also why a single misbehaving CA is dangerous: a CA that wrongly issues a cert for a domain it shouldn't can enable impersonation of that site β which is what Certificate Transparency (Chapter 12) exists to catch.
Self-Signed Certificates
A self-signed certificate is its own issuer (Subject = Issuer) with no chain to a trusted root β exactly what a root CA is, except nobody pre-trusts yours. Browsers reject it with a warning because it provides encryption but no third-party-verified authentication. They're fine for local development and internal testing (where you control both ends), but never for the public web. You can create one in a single command, which the exercises explore.
Hands-On Exercises
Use openssl s_client -connect ... -showcerts to dump the full chain a server sends, and identify each certificate's Subject and Issuer. Confirm the leaf's Issuer equals the intermediate's Subject (the links match up), and note whether the root is included in what the server sent.
Generate a self-signed certificate with a single openssl req -x509 command, inspect it to confirm Subject == Issuer, and explain in your own words exactly why a browser refuses to trust it even though the connection it provides is fully encrypted.
Find your system/browser trust store (list the installed root CAs), and reason through two scenarios: (a) a company installs its own root CA on employee laptops to inspect traffic β why does that work and what does it imply; (b) a server omits its intermediate cert β why do some clients succeed while others fail?
π View solutionChapter 5 Quick Reference
- Trust must bottom out somewhere β at a root certificate trusted inherently, not via another signature
- The trust store (root store) is the pre-shipped list of root CAs your OS/browser trusts by default
- Three tiers: Root (self-signed, offline) β Intermediate (daily issuing) β Leaf (the site's cert)
- Intermediates exist to keep the root key offline and make compromise recoverable without re-shipping trust stores
- Verification walks the chain: each cert's signature checked with the issuer's key, ending at a trusted root
- Server must send leaf + intermediates (not the root) β a missing intermediate is the #1 setup bug
- Validation levels: DV (domain control) / OV (org) / EV (legal identity) β all verify identity, not honesty
- Self-signed cert = its own issuer, no trusted chain β browser warning; fine for local dev only
- Next chapter: the TLS 1.2 handshake β putting keys, certs, and the chain together step by step
The TLS 1.2 Handshake
Everything so far β symmetric/asymmetric crypto, key exchange, certificates, the trust chain β comes together in the handshake: the short negotiation at the start of every HTTPS connection that authenticates the server and establishes the shared symmetric key. This chapter walks the TLS 1.2 handshake message by message. (Chapter 7 shows how 1.3 streamlines it; understanding 1.2 first makes that contrast clear.)
What the Handshake Must Accomplish
Before the first byte of HTTP is sent, the two parties must agree on four things. Keep these goals in mind β every message below serves one of them:
- Agree the protocol & cipher β which TLS version and cipher suite both support (Chapter 8).
- Authenticate the server β verify its certificate chains to a trusted root (Chapters 4β5).
- Establish a shared secret β via key exchange, ideally ephemeral for forward secrecy (Chapter 3).
- Confirm both sides match β verify nothing was tampered with before switching to encryption.
The Handshake, Message by Message (ECDHE)
1. ClientHello
The client opens with its capabilities: the highest TLS version it supports, a list of cipher suites it can use, a freshly generated client random (random bytes), and extensions β notably SNI (the hostname it wants, so a server hosting many sites returns the right certificate) and the supported elliptic curves.
2. ServerHello
The server replies with its choices from what the client offered: the agreed TLS version, the single cipher suite it selected, and its own server random. These two randoms aren't the secret β but they feed into deriving the final keys, ensuring every session is unique even with the same long-term key.
3. Certificate
The server sends its certificate plus the intermediate chain (Chapter 5). The client verifies it now: walks the chain to a trusted root, checks validity dates, and confirms the SAN matches the SNI hostname. If any check fails, the handshake aborts here with a warning β this is the authentication goal.
4. ServerKeyExchange (signed β the crucial step)
For ephemeral key exchange (ECDHE), the server generates its ephemeral DH public value and sends it β signed with the private key from its certificate. This single message is where Chapter 3's two roles fuse:
The signature binds the ephemeral key to the authenticated identity, defeating the man-in-the-middle: an attacker can't substitute their own DH value because they can't produce a valid signature without the server's private key. This is the heart of the handshake β authentication and key agreement joined in one step.
5. ServerHelloDone
A short marker: "I'm done with my side of the hello." The client now has everything it needs to contribute its half of the key exchange.
6. ClientKeyExchange
The client generates its ephemeral DH public value and sends it. Now both sides hold the other's DH public value, so each independently computes the same shared pre-master secret (the DiffieβHellman magic from Chapter 3 β the secret itself is never transmitted).
7. ChangeCipherSpec + Finished
Each side sends ChangeCipherSpec ("everything I send after this is now encrypted with the new keys") followed immediately by an encrypted Finished message. Finished contains a hash of the entire handshake transcript so far. Each side checks the other's Finished against its own view of the transcript:
8. Application Data
Both Finished messages verified, the tunnel is live. All HTTP now flows as encrypted, integrity-protected TLS records using the negotiated symmetric AEAD cipher (Chapter 2). The handshake is over.
Why It's "2-RTT" β and Why That Motivated 1.3
Count the round trips: ClientHello β (server's flight) β ClientKeyExchange/Finished β (server's Finished) β data. The client must wait two full round trips before sending application data. On a high-latency mobile link that's a visible delay on every new connection.
| Handshake goal | Which message(s) achieve it |
|---|---|
| Negotiate version + cipher | ClientHello / ServerHello |
| Authenticate the server | Certificate + signed ServerKeyExchange |
| Establish shared secret | ServerKeyExchange + ClientKeyExchange (ECDHE) |
| Confirm integrity / no tampering | ChangeCipherSpec + Finished (both sides) |
That 2-RTT cost β plus the lingering option of non-forward-secret RSA key transport and a menu of legacy ciphers β is exactly what TLS 1.3 set out to fix. The next chapter shows how it collapses this dance into a single round trip while removing the insecure options entirely.
Hands-On Exercises
Run openssl s_client -connect example.com:443 -tls1_2 -msg and match the messages it prints (ClientHello, ServerHello, Certificate, ServerKeyExchange, etc.) to the eight steps in this chapter. Note which messages flow before encryption begins.
Explain, step by step, how the signed ServerKeyExchange stops a man-in-the-middle from substituting their own DiffieβHellman value. Identify exactly which earlier step the signature depends on, and what the attacker would need to forge it.
π View solutionA downgrade attacker tampers with the ClientHello in transit to delete the strong cipher suites, hoping to force a weak one. Trace what happens and identify precisely which handshake message causes the connection to abort, and why the attacker can't cover their tracks.
π View solutionChapter 6 Quick Reference
- The handshake negotiates cipher, authenticates the server, establishes the shared key, and confirms integrity β before any HTTP
- ClientHello β client's versions, cipher list, client random, SNI (hostname)
- ServerHello β server's chosen version + cipher, server random
- Certificate β leaf + chain; client verifies to a trusted root & checks SAN vs SNI
- ServerKeyExchange β ephemeral DH value signed with the cert key (auth + key agreement fused; the MITM defence)
- ClientKeyExchange β client's DH value; both derive the pre-master β master secret using the two randoms
- ChangeCipherSpec + Finished β switch to encryption; Finished hashes the whole transcript (defeats downgrade/tampering)
- TLS 1.2 needs 2 round trips before data β the cost that motivated TLS 1.3
- Next chapter: TLS 1.3 β 1-RTT handshakes, 0-RTT resumption, and removed legacy crypto
TLS 1.3 β What Changed
TLS 1.3 (standardized 2018) is the version your browser uses for almost every modern HTTPS connection. It isn't a tweak of 1.2 β it's a redesign driven by two goals: make the handshake faster and make it safe by default by deleting every legacy option that caused trouble. This chapter contrasts it directly with the 1.2 handshake from Chapter 6.
Change 1: The Handshake Is Now 1-RTT
The big insight: in 1.2, the client waited for the server to choose parameters before it could contribute its key-exchange share β costing a round trip. TLS 1.3 removes the suspense. Since modern key exchange is always ephemeral (EC)DHE, the client guesses the key-exchange group and sends its DH share immediately, in the ClientHello:
{Certificate, CertVerify, Finished}π
By the time the server responds once, both sides already share the secret β so the server can send its Certificate, signature, and Finished already encrypted in that same flight, and the client can send application data right after its own Finished. One round trip instead of two. (The { } braces mark messages that are now encrypted; note the certificate itself is encrypted in 1.3, unlike 1.2 where it was sent in the clear.)
Change 2: 0-RTT Resumption (with a caveat)
For a server you've connected to before, TLS 1.3 can do even better. Using a pre-shared key (a session ticket) from the previous connection, the client can send encrypted application data in its very first message β zero round trips of waiting. This "0-RTT early data" makes repeat visits feel instant. But it comes with a sharp security trade-off:
GET /article, but dangerous for a non-idempotent action like "transfer $100" or "place order," which must never run twice. So 0-RTT is restricted to safe, idempotent requests, and forward secrecy doesn't fully apply to that early-data portion. It's an opt-in performance feature with real caveats β use deliberately, not blindly.
Change 3: Legacy Crypto Was Removed, Not Just Discouraged
TLS 1.2's flexibility was also its weakness: it still permitted weak options, and many real attacks (downgrade attacks, padding-oracle bugs) exploited them. TLS 1.3's most consequential security move was to delete the dangerous options entirely, so they can't be negotiated even by mistake:
| Removed in TLS 1.3 | Why it was dangerous |
|---|---|
| RSA key transport | no forward secrecy (Chapter 3's "harvest now, decrypt later") |
| Static (non-ephemeral) DH | also lacked forward secrecy |
| CBC-mode & RC4 ciphers | padding-oracle & keystream-bias attacks (BEAST, Lucky13, etc.) |
| Plain (non-AEAD) cipher modes | encryption without built-in integrity |
| MD5 / SHA-1 signatures | broken / collision-prone hash functions |
| Renegotiation, compression | enabled attacks like CRIME |
What's left is a short, curated list: only AEAD ciphers (AES-GCM, ChaCha20-Poly1305), only ephemeral (EC)DHE key exchange, and modern hashes. There's no weak option to downgrade to. This is the deepest lesson of the chapter: 1.3 is safer not because it added cleverness, but because it removed choices. Forward secrecy went from "available if configured" (1.2) to "mandatory and unavoidable" (1.3).
Change 4: The Cipher Suite Got Simpler
In 1.2, a cipher suite string bundled four choices together: key exchange + authentication + bulk cipher + hash (e.g. ECDHE-RSA-AES128-GCM-SHA256). In 1.3, key exchange and authentication are negotiated separately, so a "cipher suite" now names only the bulk AEAD cipher and its hash:
This is why TLS 1.3 has only a handful of cipher suites instead of hundreds β Chapter 8 reads these strings in detail.
TLS 1.2 vs 1.3 at a Glance
| TLS 1.2 | TLS 1.3 | |
|---|---|---|
| Handshake latency | 2-RTT | 1-RTT (0-RTT on resume) |
| Forward secrecy | optional | mandatory (always ephemeral) |
| RSA key transport | allowed | removed |
| Cipher modes | AEAD + legacy CBC/RC4 | AEAD only |
| Certificate sent | in the clear | encrypted |
| Cipher suite count | hundreds | five |
In practice you rarely configure any of this β modern servers and browsers negotiate TLS 1.3 automatically and fall back to 1.2 only for older peers. But understanding what changed explains why "just use the defaults" is now genuinely safe advice, which it wasn't a decade ago. The next chapter zooms into reading and choosing the cipher suites and protocol versions themselves.
Hands-On Exercises
Connect to the same server twice β once with -tls1_3 and once with -tls1_2 using openssl s_client ... -msg β and compare the message flows. Identify which messages disappear or move in 1.3, and confirm the certificate is encrypted in 1.3 but not 1.2.
Explain why TLS 1.3 can achieve 1-RTT when 1.2 needed 2-RTT. Be specific about what the client sends in the ClientHello that it couldn't before, and what assumption makes that possible (and what happens via HelloRetryRequest when the assumption is wrong).
π View solutionFor each request, decide whether it would be safe to send as 0-RTT early data and justify it: (a) GET /news/today; (b) POST /transfer?amount=500; (c) GET /account/balance; (d) POST /comments adding a comment. State the general rule you're applying.
Chapter 7 Quick Reference
- TLS 1.3 (2018) β faster and safe-by-default; a redesign, not a tweak of 1.2
- 1-RTT handshake β client sends its (EC)DHE key_share in the ClientHello, so the secret exists after one round trip
- HelloRetryRequest β fallback to 2-RTT when the client guessed the wrong key-exchange group (rare)
- The certificate is encrypted in 1.3 (it was in the clear in 1.2)
- 0-RTT resumption β repeat visits send early data with zero wait, but it's replayable β only for idempotent requests
- Legacy crypto removed: RSA key transport, static DH, CBC/RC4, non-AEAD, MD5/SHA-1, renegotiation, compression
- Safer because it removed choices β only AEAD ciphers + ephemeral (EC)DHE remain; forward secrecy is mandatory
- 1.3 cipher suites name only AEAD cipher + hash (e.g.
TLS_AES_128_GCM_SHA256) β kex/auth negotiated separately - Next chapter: cipher suites & protocol versions β reading the strings and what to enable/disable
Cipher Suites & Protocol Versions
A cipher suite is the specific combination of algorithms a TLS connection agrees to use. The intimidating strings you see in openssl output or an SSL Labs report are just those algorithm choices spelled out. Once you can read them, configuring a server's security becomes a matter of knowing which to allow β this chapter teaches both.
Anatomy of a TLS 1.2 Cipher Suite
A 1.2 suite name bundles four decisions, read left to right:
So ECDHE-RSA-AES128-GCM-SHA256 reads as: "agree the key with ephemeral elliptic-curve DiffieβHellman, authenticate the server with its RSA certificate, encrypt data with 128-bit AES in GCM mode, and use SHA-256 for hashing." Every piece is a concept from earlier chapters, now named in one line.
RSA (RSA key transport) or AESβ¦-CBC instead of GCM is a red flag. If you see ECDHE at the front and GCM (or CHACHA20-POLY1305) for the cipher, it's a modern, safe suite.
TLS 1.3 Suites Are Shorter β On Purpose
As Chapter 7 introduced, TLS 1.3 negotiates key exchange and authentication separately, so a 1.3 cipher suite names only the bulk AEAD cipher + hash:
There's no weak choice to make β key exchange is always ephemeral (EC)DHE and the cipher is always AEAD, so those decisions aren't even in the string. This is why the giant menu of TLS 1.2 suites (hundreds, many insecure) shrinks to five solid options in 1.3. In practice the top three are what you'll see; ChaCha20-Poly1305 is preferred on devices without AES hardware acceleration (most phones) because it's fast in pure software.
AES-GCM vs ChaCha20-Poly1305
Both are modern AEAD ciphers (confidentiality + integrity in one, Chapter 2) and both are secure. The choice is about performance, not safety:
| Cipher | Best when | Notes |
|---|---|---|
| AES-GCM | CPU has AES hardware (AES-NI) β most desktops/servers | extremely fast with hardware acceleration |
| ChaCha20-Poly1305 | no AES hardware β many mobile/low-power devices | fast and constant-time in pure software |
Protocol Versions: What to Enable and Disable
Separate from cipher suites is the protocol version. The guidance today is simple and worth memorizing:
| Version | Status | Action |
|---|---|---|
| SSL 2.0 / 3.0 | badly broken (POODLE) | disable β never enable |
| TLS 1.0 / 1.1 | deprecated (2021); weak crypto | disable |
| TLS 1.2 | secure if well configured | enable (for compatibility) |
| TLS 1.3 | current best | enable (preferred) |
The modern baseline is: support TLS 1.2 and 1.3, disable everything older. TLS 1.0/1.1 were officially deprecated in 2021 and browsers show warnings for them. You keep 1.2 only because some older clients can't do 1.3 yet; everything below 1.2 is a liability with no upside.
Inspecting What a Server Actually Offers
You don't have to guess a server's configuration β you can enumerate it. nmap's ssl-enum-ciphers script is the most readable tool, grading each suite:
Each suite gets a letter grade; you want all A's with no C/F entries and no TLS 1.0/1.1 sections at all. The same information underlies the SSL Labs report you'll use in Chapter 10. Reading this output is now entirely within reach β every field maps to a concept from the last six chapters.
Hands-On Exercises
Take the suite ECDHE-ECDSA-AES256-GCM-SHA384 and decode all four parts (key exchange, authentication, bulk cipher, hash). State which guarantee each part contributes, and whether this suite provides forward secrecy.
Use openssl ciphers -v 'ECDHE+AESGCM' to list matching suites, then run nmap --script ssl-enum-ciphers against a real site. Identify the protocol versions it supports and whether any weak suite or deprecated version is present.
Given these four suites, classify each as MODERN-SAFE or AVOID and justify: (a) TLS_AES_128_GCM_SHA256; (b) ECDHE-RSA-AES128-GCM-SHA256; (c) AES256-SHA (i.e. RSA kex, CBC); (d) ECDHE-RSA-RC4128-SHA. State the single biggest problem with each "avoid" one.
Chapter 8 Quick Reference
- A cipher suite = the agreed combination of algorithms for a connection
- TLS 1.2 suite = key exchange β authentication β bulk cipher β hash (e.g. ECDHE-RSA-AES128-GCM-SHA256)
- Check the first two segments: ECDHE/DHE = forward secrecy; GCM/ChaCha20 = modern AEAD
- TLS 1.3 suite = just AEAD cipher + hash (e.g. TLS_AES_128_GCM_SHA256) β only five exist, all safe
- AES-GCM (fast with AES hardware) vs ChaCha20-Poly1305 (fast in software, mobile) β both secure
- Versions: enable TLS 1.2 + 1.3, disable SSL 2/3 and TLS 1.0/1.1 (deprecated 2021)
- On 1.2 curate the suite list (exclude RSA-kex, CBC, RC4, 3DES, EXPORT, NULL); on 1.3 there's little to misconfigure
- Audit with
nmap --script ssl-enum-ciphersoropenssl ciphers -vβ aim for all A's, no weak entries - Next chapter: getting a certificate β CSRs, domain validation, Let's Encrypt & ACME
Getting a Certificate β Let's Encrypt & ACME
The theory is done β now the practical question: how do you actually obtain a certificate for a domain you own? This chapter covers the request itself (the CSR), how a CA proves you control the domain (validation), and how Let's Encrypt automated the whole thing into a single command via the ACME protocol β the reason HTTPS is now free and ubiquitous.
Step Zero: The Key Pair Never Leaves Your Server
Before anything else, one principle that surprises beginners: you generate your own private key, and it never leaves your server. The CA never sees it. You only send the CA your public key (inside a CSR) plus proof you control the domain; the CA signs a certificate binding that public key to your domain and sends the certificate back. The secret half stays with you the entire time.
The CSR β Certificate Signing Request
A CSR is the formal application you send to a CA. It bundles your public key with the identity you're requesting (the domain), and is signed by your private key to prove you hold it. You can create one with openssl:
| The CSR contains | The CSR does NOT contain |
|---|---|
| your public key | your private key (never!) |
| the requested domain(s) β CN & SAN | the validity dates (the CA sets those) |
| a self-signature proving key ownership | the CA's signature (added on issuance) |
Inspect a CSR with openssl req -in example.csr -text -noout β you'll see the same fields as a certificate (Chapter 4) minus the issuer and validity, because those are filled in only when a CA signs it.
Domain Validation: Proving You Control the Domain
A CA won't sign a cert for example.com until you prove you actually control that domain (Chapter 5's DV level). The proof is a challenge: the CA gives you something to place where only the domain's controller could put it, then checks for it.
| Challenge type | You prove control by⦠| Best for |
|---|---|---|
| HTTP-01 | serving a specific token file at http://domain/.well-known/acme-challenge/<token> | a single host you run a web server on |
| DNS-01 | creating a specific TXT record in the domain's DNS | wildcards (*.example.com) & servers not publicly reachable |
| TLS-ALPN-01 | presenting a special cert on a TLS connection | environments where only port 443 is usable |
The logic is identical across all three: only someone who genuinely controls the domain (its web root, its DNS, or its TLS endpoint) could satisfy the challenge. Wildcard certificates specifically require DNS-01, because proving control of one web page doesn't prove control of every possible subdomain β but control of the DNS zone does.
ACME β Automating the Whole Exchange
ACME (Automatic Certificate Management Environment) is the protocol Let's Encrypt introduced to turn that manual back-and-forth into an automated machine-to-machine conversation. A client (like certbot) runs the entire flow:
In practice this is one command. Certbot can even configure your web server for you:
Renewal: Set It and Forget It
Because Let's Encrypt certs last only 90 days, renewal must be automatic β and certbot installs a timer that does it for you. The renewal re-runs the same validation; nothing manual is required as long as the challenge can still be satisfied:
--test-cert / --staging) so failed experiments don't burn your weekly quota β staging certs aren't publicly trusted but exercise the full flow. Second, after a renewal your server is often still using the old cert in memory until it reloads β so a renewal deploy hook (e.g. --deploy-hook "systemctl reload nginx") is needed to pick up the new cert. A silently-not-reloaded server is a classic "why did my cert expire when certbot said it renewed?" bug.
When You'd Use a Commercial CA Instead
Let's Encrypt covers the overwhelming majority of needs, but not all. You'd pay a commercial CA when you need OV/EV validation (vetted organization identity, Chapter 5), longer support contracts, warranties, or certificate types Let's Encrypt doesn't issue. For ordinary "encrypt my website" purposes, though, free DV via ACME is the default choice β and the rest of this course assumes it.
Hands-On Exercises
Generate a private key and a CSR for a domain with both a CN and a SAN list, then inspect the CSR with openssl req -text -noout. Confirm it contains your public key and requested domains but NOT a private key, issuer, or validity dates β and explain why those three are absent.
Explain how the HTTP-01 and DNS-01 challenges each prove domain control, then state which one you MUST use to obtain a wildcard certificate for *.example.com and exactly why the other one can't work for a wildcard.
A site's certificate expired even though the admin "set up certbot." List the most likely causes (renewal timer not running, server never reloaded the renewed cert, validation challenge now failing) and describe how certbot renew --dry-run and a deploy hook would have prevented it.
Chapter 9 Quick Reference
- You generate your private key; it never leaves your server β the CA only ever sees your public key
- CSR = public key + requested domains (CN/SAN), self-signed to prove key ownership; no issuer/validity yet
- Domain validation (DV) proves control via a challenge: HTTP-01 (token file), DNS-01 (TXT record), or TLS-ALPN-01
- Wildcards require DNS-01 β only DNS-zone control proves authority over every subdomain
- ACME automates the order β challenge β validate β CSR β issue flow; certbot is the common client
- Let's Encrypt β free, automated, DV-only CA; the reason HTTPS became ubiquitous
- 90-day certs β auto-renewal (certbot timer); test with
certbot renew --dry-run - Gotchas: rate limits β use staging while testing; reload the server via a deploy hook after renewal
- Next chapter: configuring HTTPS on a server β nginx/Apache, redirects, HSTS, OCSP stapling, SSL Labs
Configuring HTTPS on a Server
You have a certificate (Chapter 9). Now you wire it into a web server correctly β not just "it works," but configured so the grading tools give you an A. This chapter is the practical payoff: the handful of directives that matter, the mistakes that cost a grade, and how to verify the result.
The Minimum: Certificate, Key, and Protocols
A basic TLS server block needs three things: the certificate chain, the private key, and which protocols/ciphers to allow. Here's an nginx example carrying everything from the last two chapters:
fullchain.pem (leaf plus intermediates) and privkey.pem. Point ssl_certificate at fullchain.pem. If you accidentally use cert.pem (the leaf alone), you recreate exactly the Chapter 5 "missing intermediate" bug: it works in some browsers (which cache the intermediate) and fails on other clients with "unable to get local issuer certificate." This is the single most common server-config TLS mistake β get this one line right.
Redirect HTTP β HTTPS
Serving HTTPS isn't enough if visitors can still reach plain HTTP. Add a second server block on port 80 that redirects everything to HTTPS, so no one accidentally uses the insecure version:
A 301 (permanent) redirect tells browsers and search engines the HTTPS URL is canonical. But a redirect alone has a subtle gap β which is exactly what HSTS closes.
HSTS β Don't Even Try HTTP Next Time
A plain redirect still involves one insecure HTTP request first (the one that gets redirected) β and an active attacker could intercept that initial request before the redirect happens (an "SSL stripping" attack, Chapter 11). HSTS (HTTP Strict Transport Security) fixes this with a response header that tells the browser: for the next N seconds, never use HTTP for this domain at all β go straight to HTTPS yourself.
After the first secure visit, the browser refuses to make any plaintext request to the domain for a year (max-age=31536000), eliminating the vulnerable first hop on every subsequent visit. includeSubDomains extends the rule to all subdomains.
max-age β there's no clickthrough. If your HTTPS later breaks (expired cert, misconfiguration), users are locked out, not merely warned, until you fix it or the max-age elapses. So roll it out gradually: start with a short max-age (e.g. 300), confirm everything's solid, then raise it to a year. The preload list (hardcoded into browsers) is even more permanent β only submit once you're certain.
OCSP Stapling β Faster, More Private Revocation Checks
Browsers want to know a cert hasn't been revoked (Chapter 11). The old way: the browser separately contacts the CA's OCSP responder β which is slow and leaks to the CA which sites you visit. OCSP stapling flips this: the server periodically fetches a fresh, CA-signed "this cert is still valid" proof and staples it to the TLS handshake, so the browser gets it instantly without contacting the CA.
It's a win on every axis: faster handshakes (no extra round trip to the CA), better privacy (the CA doesn't see each visitor), and less load on the CA. It's a standard part of a well-tuned config.
The Apache Equivalent
| Purpose | nginx | Apache |
|---|---|---|
| Cert (full chain) | ssl_certificate fullchain.pem | SSLCertificateFile fullchain.pem |
| Private key | ssl_certificate_key privkey.pem | SSLCertificateKeyFile privkey.pem |
| Protocols | ssl_protocols TLSv1.2 TLSv1.3 | SSLProtocol -all +TLSv1.2 +TLSv1.3 |
| HSTS | add_header Strict-Transport-Security ... | Header always set Strict-Transport-Security ... |
| OCSP stapling | ssl_stapling on; | SSLUseStapling on |
The concepts are identical β only the directive names differ. Certbot's --nginx / --apache plugins generate much of this for you, but knowing what each line does is what lets you debug and harden it.
Verify: Grade It with SSL Labs
Don't guess whether your config is good β measure it. Qualys SSL Labs (ssllabs.com/ssltest) runs a deep audit and assigns a letter grade, checking everything from this course: protocol versions, cipher suites, chain completeness, HSTS, key strength, and known vulnerabilities.
testssl.sh gives similar results from the command line.)
Hands-On Exercises
Write a complete nginx configuration for example.com that: serves the full chain + key, supports only TLS 1.2/1.3, redirects HTTPβHTTPS with a 301, and sets a one-year HSTS header with includeSubDomains. Annotate which line prevents the missing-intermediate bug and why.
π View solutionExplain the gap that a plain HTTPβHTTPS redirect leaves open, then explain precisely how HSTS closes it. Include why HSTS only protects after the first secure visit, and what the preload list does about that residual first-visit gap.
π View solutionDescribe what OCSP stapling is and the three problems it solves versus a browser doing its own OCSP lookup. Then list what an SSL Labs A+ grade requires, mapping each requirement back to the chapter that introduced it.
π View solutionChapter 10 Quick Reference
- Minimum config: ssl_certificate (full chain) + ssl_certificate_key + ssl_protocols TLSv1.2 TLSv1.3
- Use fullchain.pem, never
cert.pemβ the leaf-only file recreates the missing-intermediate bug - Redirect HTTPβHTTPS with a
301on a port-80 server block - HSTS (
Strict-Transport-Security) β browser auto-upgrades to HTTPS, closing the redirect's insecure first hop (SSL-stripping defence) - HSTS is a commitment: long max-age locks users out if HTTPS breaks β start short, then raise; preload is near-permanent
- OCSP stapling β server staples a fresh CA-signed validity proof: faster handshake, better privacy, less CA load
- Apache uses the same concepts with
SSLCertificateFile,SSLProtocol,SSLUseStapling, etc. - Verify with SSL Labs (or
testssl.sh) β an A+ is a checklist of this whole course - Next chapter: common problems & attacks β expired/mismatched certs, mixed content, downgrade & SSL-stripping, revocation
Common Problems & Attacks
You now understand how TLS is supposed to work. This chapter is the troubleshooting and threat catalogue: the certificate errors you'll actually hit, the attacks TLS defends against (and how), and the failure modes that still bite well-meaning admins. Each one connects back to a guarantee or mechanism from earlier chapters.
Certificate Errors β What the Browser Is Really Telling You
Most "your connection is not private" warnings come from one of a few failed checks β all from Chapters 4β5. Knowing which check failed tells you exactly what to fix:
| Error | Failed check | Usual cause / fix |
|---|---|---|
| CERT_DATE_INVALID | validity window (Ch. 4) | cert expired β renew it (auto-renewal, Ch. 9) |
| COMMON_NAME_INVALID | SAN β hostname (Ch. 4) | cert doesn't list the domain visited β reissue with correct SAN |
| AUTHORITY_INVALID | chain to trusted root (Ch. 5) | self-signed, or missing intermediate β install full chain |
| unable to get local issuer | incomplete chain (Ch. 5) | server sent leaf only β use fullchain.pem (Ch. 10) |
Mixed Content β HTTPS Page, HTTP Resources
A page served over HTTPS that pulls in sub-resources over plain HTTP is mixed content. It quietly defeats the page's security: those HTTP requests are unencrypted and tamperable, so the "secure" page isn't actually secure end-to-end.
Browsers split this into two severities: active mixed content (scripts, stylesheets, iframes β things that can alter the page) is blocked outright, while passive mixed content (images, media) triggers a downgraded padlock warning. The fix is to load every resource over HTTPS (use https:// or protocol-relative URLs), and a Content-Security-Policy: upgrade-insecure-requests header can auto-rewrite stragglers.
SSL Stripping & Downgrade Attacks
Two related man-in-the-middle attacks, both already half-covered in earlier chapters β here's how they're defeated:
- SSL stripping β the attacker intercepts the victim's initial plaintext request and keeps them on HTTP, proxying to the real HTTPS site so the user never sees a warning. Defeated by HSTS (Chapter 10): the browser refuses HTTP for the domain, so there's no plaintext request to strip. Preload closes even the first-visit gap.
- Protocol/cipher downgrade β the attacker tampers with the cleartext ClientHello to force a weak protocol or cipher. Defeated by the Finished hash (Chapter 6), which covers the whole transcript, plus TLS 1.3 simply removing the weak options to downgrade to (Chapter 7).
Implementation Bugs: Heartbleed and Friends
The protocol can be sound while the code implementing it is flawed. The famous example is Heartbleed (2014): a buffer over-read bug in OpenSSL's TLS heartbeat extension let an attacker read up to 64 KB of server memory per request β potentially leaking private keys, session cookies, and passwords, with no trace in logs.
Revocation: Cancelling a Certificate Before It Expires
When a key is compromised (as in Heartbleed) or a cert is mis-issued, you need to invalidate it before its natural expiry. That's revocation, and it has historically been the weakest link in the PKI:
| Mechanism | How it works | Weakness |
|---|---|---|
| CRL | CA publishes a big list of revoked serial numbers | large, slow to download, cached stale |
| OCSP | browser asks the CA about one cert in real time | slow, privacy-leaking, often "soft-fail" |
| OCSP stapling | server staples a fresh CA-signed status (Ch. 10) | needs server support |
Certificate Pinning β Powerful and Dangerous
Pinning hard-codes which specific certificate or public key an app expects, so even a validly-issued cert from a different (possibly fraudulent) CA is rejected. It defends against the Chapter 5 risk of a misbehaving CA. But it's a sharp tool:
Hands-On Exercises
Use badssl.com (or openssl against it) to trigger several deliberate certificate errors β expired, wrong-host, self-signed, untrusted-root. For each, name the exact check that failed and which chapter's concept it maps to.
π View solutionFor each attack β (a) SSL stripping, (b) protocol downgrade, (c) passive eavesdropping, (d) a stolen server key used to decrypt old recorded traffic β name the specific TLS mechanism that defends against it and the chapter that introduced that defence.
π View solutionA server running a vulnerable OpenSSL version is found to be exposed to Heartbleed. Write the full remediation checklist in the correct order, and explain why simply patching OpenSSL is insufficient. Then explain why short-lived certificates reduce reliance on revocation.
π View solutionChapter 11 Quick Reference
- Cert errors map to failed checks: DATEβvalidity, COMMON_NAMEβSAN, AUTHORITY/local-issuerβchain (Ch. 4β5)
- Mixed content β HTTP sub-resources on an HTTPS page; active (scripts) blocked, passive (images) warned; load all over HTTPS
- SSL stripping β defeated by HSTS (Ch. 10); downgrade β defeated by the Finished hash + TLS 1.3 removing weak options
- Heartbleed β an implementation bug (OpenSSL) leaking memory incl. private keys; protocol-sound β code-safe
- Key compromise = patch β new key β reissue β revoke old β reset credentials; patching alone is not enough
- Revocation: CRL / OCSP / OCSP stapling β but checks often soft-fail, so short-lived certs are the real mitigation
- Pinning defends against rogue CAs but can brick your site; browser HPKP was removed β survives mainly in mobile apps
- Every attack maps to a defence already learned β TLS is layered, each mechanism neutralizing one attack class
- Next chapter: beyond the basics β mTLS, Certificate Transparency, and the modern PKI ecosystem
Beyond the Basics
You've covered the full path from "why HTTPS" to running a hardened server. This final chapter surveys the frontier β the mechanisms that secure machine-to-machine systems, keep the CA ecosystem honest, and define where TLS is heading β so you know what exists and where to go next.
Mutual TLS (mTLS) β Both Sides Present Certificates
In ordinary HTTPS, only the server proves its identity; the client stays anonymous (it logs in separately with a password). Mutual TLS adds the symmetric half: the client also presents a certificate, and the server verifies it the same way the client verified the server. Both ends are cryptographically authenticated before any data flows.
| Normal TLS | Mutual TLS (mTLS) | |
|---|---|---|
| Server authenticated? | yes (certificate) | yes (certificate) |
| Client authenticated? | no (anonymous) | yes (client certificate) |
| Typical use | the public web | service-to-service, APIs, zero-trust networks |
mTLS isn't used for the public web (you can't issue a cert to every visitor), but it's foundational for internal systems: microservices authenticating each other, API clients, VPNs, and "zero-trust" architectures where every connection β even inside the network β must prove identity. Service meshes like Istio automate mTLS between every pod. It's the same handshake you learned in Chapter 6, with one extra step: the server requests and verifies a client certificate.
Certificate Transparency β Keeping CAs Honest
Chapters 5 and 11 raised the deep risk: a trusted CA could mis-issue a certificate for a domain β say, an attacker (or a compromised/coerced CA) obtaining a valid cert for yourbank.com they don't own. Chain verification wouldn't catch it; the cert is genuinely trusted. Certificate Transparency (CT) is the ecosystem's answer.
CT requires every issued certificate to be published to public, append-only, cryptographically-verifiable logs. Browsers refuse certificates that aren't accompanied by proof of CT logging. The effect:
- Nothing issues in secret β every cert for your domain becomes publicly visible, whoever requested it.
- Domain owners can monitor β you can watch the logs (or use a service) and get alerted if any cert is issued for your domain that you didn't request.
- Mis-issuance gets caught β several CAs have been distrusted after CT logs exposed bad behaviour.
crt.sh β type any domain and see every certificate ever issued for it. It's the safer successor to certificate pinning (Chapter 11) for the rogue-CA problem.
The CA/Browser Ecosystem
The rules that hold all this together aren't ad hoc. The CA/Browser Forum β browser vendors and CAs together β sets the Baseline Requirements every public CA must follow: validation standards, maximum certificate lifetimes, mandatory CT logging, key-strength minimums. Browser root programs (Mozilla, Apple, Microsoft, Chrome) decide which CAs are trusted and can distrust a CA that breaks the rules β a commercial death sentence that keeps CAs disciplined. The trust store you inspected in Chapter 5 is the output of these programs.
Where TLS Is Heading
| Trend | What it does |
|---|---|
| Encrypted Client Hello (ECH) | encrypts the SNI hostname in the handshake β closing the last big metadata leak (Chapter 1's "domain is still visible") |
| Ever-shorter cert lifetimes | industry moving toward ~47-day (and shorter) certs β making revocation matter even less (Chapter 11) |
| Post-quantum cryptography | new key-exchange/signature algorithms resistant to quantum attacks; hybrid PQ key exchange already shipping in browsers |
| Automation everywhere | ACME for internal CAs, shorter renewals, less manual TLS handling overall |
The Whole Course in One Mental Model
Step back and the entire course collapses into a single sentence you can now unpack completely: HTTPS uses asymmetric cryptography and a CA-issued, transparency-logged certificate to authenticate the server and agree β with forward secrecy β on a symmetric key, which then protects every byte with confidentiality and integrity. Every term in that sentence is a chapter you've worked through.
Where to Go Next
- Read a real handshake in Wireshark β capture a TLS 1.3 connection and watch the messages from Chapters 6β7 on the wire.
- Run your own internal CA with
step-caorcfssl, and try issuing client certs for mTLS. - The standards themselves β RFC 8446 (TLS 1.3) is surprisingly readable now that you have the concepts.
- Get an A+ on a real domain β apply Chapters 9β10 end to end and verify with SSL Labs.
- Explore crt.sh for your own domains and set up CT monitoring alerts.
Hands-On Exercises
Explain how mTLS differs from normal TLS in terms of who authenticates whom, and give two concrete scenarios where mTLS is appropriate and one where it is not. Tie the mechanism back to the Chapter 6 handshake β what one extra step does mTLS add?
π View solutionSearch crt.sh for a domain you control (or a well-known one) and examine the issued certificates. Explain what problem Certificate Transparency solves, why it's described as "detection not prevention," and how it improves on certificate pinning for the rogue-CA problem.
Explain why post-quantum cryptography is being deployed now rather than waiting for quantum computers to exist, explicitly connecting it to the "harvest now, decrypt later" attack from Chapter 3. Then write the one-sentence summary of the whole course and label which chapter each key term came from.
π View solutionChapter 12 Quick Reference
- mTLS β both client AND server present certificates; for service-to-service, APIs, zero-trust (not the public web)
- mTLS = the Chapter 6 handshake + one extra step: server requests & verifies a client certificate
- Certificate Transparency (CT) β every cert published to public append-only logs; browsers require it
- CT is detection, not prevention β mis-issuance can't hide; monitor your domains via
crt.sh - CT is the safer successor to pinning for the rogue-CA problem (Chapter 11)
- CA/Browser Forum + browser root programs set the rules and can distrust misbehaving CAs
- Frontier: ECH (encrypts SNI), ever-shorter certs, post-quantum key exchange (vs harvest-now-decrypt-later)
- Next steps: Wireshark a handshake, run an internal CA + mTLS, read RFC 8446, get an A+ on a real site
β HTTPS / TLS Fundamentals Complete β 12 / 12 chapters
From plaintext HTTP's three weaknesses, through the cryptographic primitives, key exchange, certificates and the chain of trust, both handshakes, cipher suites, obtaining and configuring certificates, the attack catalogue, and the modern PKI frontier. You can now read a TLS handshake, configure HTTPS to an A+, diagnose certificate errors, and reason about the guarantees β confidentiality, integrity, authentication β that every secure connection rests on.