You log into your bank on café wi-fi. Between your laptop and the bank sit the router, the café's ISP, several backbone networks and the bank's ISP. Every one of them can see the traffic passing through.
Over plain HTTP, your password crosses all of them in readable text. Anyone in that path — or anyone else on the same wi-fi — can read it, and can also silently modify the page you receive.
HTTPS is HTTP carried inside TLS, and it exists to make that path untrustworthy without being dangerous.
The three guarantees
TLS provides exactly three things. Knowing them precisely matters, because people routinely assume a fourth that does not exist.
Encryption. Anyone reading the traffic sees unusable bytes. Confidentiality against passive eavesdropping.
Integrity. Any modification in transit is detected and the connection fails. An ISP cannot inject advertisements into a page, and an attacker cannot flip a digit in a transfer amount.
Authentication. You are talking to the server you think you are. This is what makes the other two useful — encryption to an impostor protects nothing.
SSL, TLS, and the naming confusion
SSL was the original protocol. Every version is broken and deprecated. TLS replaced it: 1.0 and 1.1 are deprecated, 1.2 is the acceptable minimum, and 1.3 is current and meaningfully better.
The industry kept saying "SSL" out of habit — "SSL certificate", "SSL termination" — but in practice everyone means TLS. Say TLS; recognise SSL as the old name.
The handshake
Before any application data flows, client and server negotiate. Understanding this explains several performance decisions elsewhere in the course.
Diagram, as text
- Client leads to Server (1. hello, supported ciphers)
- Server leads to Client (2. certificate + chosen cipher)
- Client leads to Server (3. verify cert, agree keys)
- Client leads to Server (4. encrypted application data)
Hello. The client offers the TLS versions and cipher suites it supports.
Certificate. The server returns its certificate, which contains its public key and a signature from a certificate authority.
Verification. The client checks the certificate: is it signed by a CA the system trusts, is it for this hostname, has it expired, has it been revoked? Any failure ends the connection.
Key agreement. Both sides derive a shared symmetric key. Modern TLS uses ephemeral Diffie-Hellman, which gives forward secrecy — a property worth knowing: even if the server's private key is stolen later, previously recorded traffic cannot be decrypted, because the session key was never transmitted and is not derivable from the certificate.
Application data then flows under fast symmetric encryption. Public-key cryptography is used only to establish the session, because it is far too slow for bulk data.
Why the handshake matters for performance
TLS 1.2 needs two additional round trips before any data moves. On a connection with 100ms latency that is 200ms of pure overhead.
TLS 1.3 reduces this to one round trip, and supports zero-round-trip resumption for repeat visitors.
This is why the CDN lesson mentioned TLS termination at the edge — moving the handshake close to the user removes most of that cost, because the expensive part is round trips, not computation.
Certificates and trust
A certificate binds a public key to a hostname, signed by a certificate authority. Your operating system and browser ship with a list of CAs they trust, and trust chains from those roots through intermediates to your certificate.
Three validation levels exist — domain, organisation and extended validation — and honestly, browsers no longer display them differently, so domain validation is fine for almost everyone. Free automated certificates from Let's Encrypt are the norm.
Certificates expire, typically in 90 days now, and an expired certificate is a full outage: browsers refuse the connection entirely. Automate renewal, and alert well before expiry. Manual renewal is a recurring, entirely avoidable incident.
Configuration that actually matters
Redirect HTTP to HTTPS, and then go further — a redirect still leaves the first request in plaintext, where it can be intercepted.
HSTS fixes that. The header tells browsers to use HTTPS for this domain for a stated period, without asking:
Strict-Transport-Security: max-age=31536000; includeSubDomainsAfter the first visit, the browser refuses plain HTTP entirely, which defeats downgrade attacks.
Disable old protocols and weak ciphers. Turn off SSL entirely and TLS 1.0/1.1. Supporting an obsolete cipher for one legacy client weakens the connection for everyone, because an attacker can force negotiation down to it.
Secure cookies. As in the LLD security lesson: Secure so cookies never travel over HTTP, HttpOnly so JavaScript cannot read them, SameSite to blunt CSRF.
Certificate pinning for mobile apps pins the expected certificate so a compromised CA cannot impersonate you. Powerful and dangerous — pin wrongly and you brick your app until users update.
Encryption in transit versus at rest
Two distinct problems, often conflated.
In transit is TLS, covered above.
At rest protects stored data — disk encryption, encrypted database volumes, encrypted backups. It defends against stolen hardware and misconfigured storage buckets, and it is frequently a compliance requirement.
Note what at-rest encryption does not do: if an attacker compromises your running application, it reads data through the application, which has the keys. At-rest encryption protects the disk, not the process.
Internal traffic needs TLS too. Terminating TLS at the load balancer and sending plaintext to backends is common and assumes your internal network is trustworthy. Zero-trust architecture — covered later in this module — rejects that assumption.
Check your understanding
Common mistakes
Manual certificate renewal. Expiry is an outage, and it is entirely predictable. Automate it.
Disabling certificate verification to fix an error. verify=False in a client library, or accepting all certificates in a mobile app, silently removes the authentication guarantee — leaving encryption to an attacker who can now impersonate anyone.
Mixed content. An HTTPS page loading a script over HTTP lets an attacker replace that script and control the page. Browsers block it; developers sometimes work around the block.
Assuming the internal network is safe. Anything that reaches your network reaches unencrypted internal traffic.
Treating HTTPS as "we are secure". It secures one layer against one class of attack.
Practice
A colleague says 'we encrypt the database at rest, so a breach would not expose customer data'. Explain precisely what encryption at rest does and does not protect against.
Write your own answer first, on paper or in a note. Then compare.
Show a hint
Ask which attacker is stopped, and what the running application can read.
Show a strong answer
What encryption at rest actually protects against: physical access to the storage medium. A stolen disk, a decommissioned drive that was not wiped, a backup tape that goes missing, or a cloud volume snapshot copied by someone with storage-layer access but not database access. In those cases the bytes are unreadable without the key, and that is a real and worthwhile protection — it is also what most compliance regimes are asking for.
What it does not protect against — which is nearly every realistic breach:
- A compromised application. The running service holds a valid connection and the database decrypts transparently for it. SQL injection, a leaked credential or a remote code execution reads plaintext, because that is exactly what the encryption is designed to permit.
- A compromised database account. Same reasoning — the encryption is below the authorisation layer, not above it.
- A malicious or compromised administrator, if the key is available to the same environment.
- Data in transit inside your network, or in logs, caches, message queues and exports — all of which routinely contain the same customer data and are usually not covered by the database's at-rest encryption at all.
The honest summary: at-rest encryption defends against someone who obtains the storage, not against someone who obtains access. Most breaches are the second kind.
What would meaningfully reduce exposure: encrypting particular sensitive fields with keys the application must request separately, so a compromise of the database alone yields ciphertext; minimising what is collected and retained; and making sure logs, backups and analytics copies are held to the same standard as the primary store.
Design the TLS configuration decisions for a new public API, and say which ones are worth arguing about and which are settled.
Write your own answer first, on paper or in a note. Then compare.
Show a hint
Distinguish the choices that still have trade-offs from the ones with a single right answer.
Show a strong answer
Settled — no discussion needed:
- TLS 1.3, with 1.2 permitted only if you must support old clients. Everything earlier is broken and should be refused. 1.3 also completes in one round trip rather than two, so this is a latency improvement as well as a security one.
- Strong cipher suites only, using the modern defaults rather than a hand-curated list. Hand-curated lists rot; a maintained default does not.
- HSTS, with a long max-age, so browsers refuse plaintext to your domain after the first visit. Consider preloading once you are confident, because that removes even the first request.
- Certificates issued and renewed automatically. The most common TLS outage is an expired certificate, and automation removes the entire class.
Genuinely worth arguing about:
- Where TLS terminates. At the load balancer is simplest and means traffic inside your network is plaintext. Re-encrypting to the backend costs CPU and complexity and is the right call when the network between them is not fully trusted — which, in a shared cloud environment, is a defensible position either way.
- Whether to require client certificates (mutual TLS). Strong authentication for service-to-service traffic, and a real operational burden: every client needs a certificate, and rotation becomes a distributed problem. Usually right internally, usually wrong for a public API.
- Certificate pinning in mobile clients. It defeats interception by a device-installed root, and it has bricked applications when a certificate changed unexpectedly. If you do it, pin to a key you control and always ship a backup pin.
The pattern: the cryptographic choices are settled and should be delegated to defaults; the architectural choices — where trust boundaries sit — are the ones that need a decision.
Key takeaways
- TLS provides exactly three things: encryption, integrity and authentication — and only in transit.
- SSL is the dead predecessor. Require TLS 1.2 minimum, prefer 1.3.
- The handshake verifies a CA-signed certificate, then agrees a fast symmetric key with forward secrecy, so stolen keys cannot decrypt past traffic.
- The handshake costs round trips, which is why TLS termination at the edge is worth doing.
- Automate certificate renewal — expiry is a complete outage.
- Add HSTS, because a redirect still leaves the first request in plaintext.
- At-rest encryption is a separate problem, and it does not protect against a compromised application.
Further reading
- RFC 8446, The Transport Layer Security (TLS) Protocol Version 1.3.
- RFC 6797, HTTP Strict Transport Security (HSTS).
- Ross Anderson, Security Engineering, third edition (Wiley, 2020) — the standard reference for what protects what.
- Mozilla, Server Side TLS configuration guidelines — maintained defaults rather than hand-curated cipher lists.
- Peter Gutmann, "Secure Deletion of Data from Magnetic and Solid-State Memory" (USENIX 1996) — why at-rest protection matters for decommissioned media.