Security · 16 min

HTTPS

Follow one password typed on café Wi-Fi, first over plain HTTP, where anyone nearby can read it, then over HTTPS: a secret agreed in public, a certificate that proves who the server is, and encryption for everything after.

You are in a café, on its free Wi-Fi. You open shop.example, type your email and the password matcha-latte-42, and press Log in.

Your laptop has no cable. It sends every byte through the air by radio, and every laptop in the room can pick it up. So who else can read that password?

This article follows that one password from your keyboard to the shop’s server, twice. First over plain HTTP, then over HTTPS. Each time, you watch what the person at the next table can read.

Trip one: the password in plain sight

When you press Log in, your browser writes this text, 185 bytes of it:

POST /login HTTP/1.1
Host: shop.example
Cookie: cart=7f3a91c2
Content-Type: application/x-www-form-urlencoded
Content-Length: 49

email=maya%40example.com&password=matcha-latte-42
Your password is on the last line, as typed. %40 is how a form writes the @ sign.

The browser hands it to the network, which wraps it in envelopes for the trip (the Network layers concept builds those envelopes one by one). None of those envelopes hides what is inside. They only add addresses.

On open Wi-Fi, anyone nearby can record every packet (one small chunk of data in flight) with a free tool such as Wireshark. Even easier, they can run a hotspot from their own laptop called “Cafe Free WiFi” and wait for you to join. Then every byte you send goes through their machine.

And the café is only the first stop. The same bytes then pass 10 to 20 routers run by companies you have never heard of. Any of them can read the password, the cookie and the page you asked for. Worse, any of them can change the bytes: swap the shop’s page for a fake one, or add a script to it.

To fix this, the password needs three things, in this order:

  1. A secret that only your browser and the server know, agreed while the whole café listens.
  2. Proof that the one who agreed it with you really is shop.example, and not the laptop at the next table.
  3. The request scrambled with that secret, so only the server can read it and any change is noticed.

The hard part is the first one. Encryption is easy once both sides share a key. But you have never met this server, and anything you send to agree on a key, the café hears too.

Agreeing a secret while the café listens

Here is how two strangers can agree a secret out loud, with numbers small enough to check in your browser’s console. Everyone, including the listener, knows two public numbers: 5 and 23.

  1. Your browser picks a private number, 6, and tells nobody. It works out 5 ** 6 % 23, which is 15625 % 23 = 8. It sends 8.
  2. The server picks its own private number, 7. It works out 5 ** 7 % 23, which is 78125 % 23 = 17. It sends 17.
  3. Your browser takes the server’s 17 and its own 6: 17 ** 6 % 23 = 12.
  4. The server takes your 8 and its own 7: 8 ** 7 % 23 = 12.

Both got 12, and 12 was never sent. Why do they match? 17 is what is left of 5 multiplied by itself 7 times, so the browser computed 5 multiplied by itself 7 × 6 = 42 times. The server computed 5 multiplied by itself 6 × 7 = 42 times. Same number. Taking % 23 along the way doesn’t change the final remainder, and you can check: in the console, 5n ** 42n % 23n also gives 12n (the n makes JavaScript use exact whole numbers, since 5 to the 42nd is too big for a normal one).

The listener heard 5, 23, 8 and 17. To get 12, it needs one of the private numbers: “which power of 5 leaves 8 after % 23?” With 23 it can just try all 22 powers. That is the only weakness, and it is a matter of size.

Real browsers do the same dance with private numbers about 77 digits long. Going forwards still takes well under a millisecond. Going backwards, trying every one of the 2²⁵⁶ possible private keys is out of the question. The best known shortcut cuts that to about 2¹²⁸ steps, roughly 3.4 × 10³⁸. At a billion billion (10¹⁸) steps a second, that is 3.4 × 10²⁰ seconds. The universe is about 4.4 × 10¹⁷ seconds old, so that is nearly 800 times its age.

Real browsers use a version of this built on elliptic curves, called ECDH. The maths differs, but the shape is the same: easy forwards, hopeless backwards. The demo runs it for real in your browser, with the curve called P-256.

But who did you agree it with?

Now the trap. Your browser said hello to “shop.example”, and someone answered. On café Wi-Fi, the fake hotspot can answer itself.

It agrees one secret with you and a second secret with the real shop. Then it sits in the middle: it decrypts what you send, reads your password, encrypts it again and passes it on. You both see working encryption. This is called a man-in-the-middle attack.

The key exchange can’t catch it, because it only proves you share a secret with whoever answered. You need the answer to come with proof of who is speaking.

An ID card for a website

That proof is built from signatures.

Let’s Encrypt, a free CA, checks by asking the requester to put a given file on the site, then fetching it. Only someone who runs shop.example can do that.

Why would your browser believe a CA? Because your browser or operating system ships with a list of about 150 root certificates it trusts. Root CAs keep their private keys on machines with no network, in locked rooms, brought out only a few times a year. So a root signs a few intermediate certificates, and the intermediates do the daily work of signing websites. That gives a chain:

  1. shop.example’s certificate, signed by the intermediate.
  2. The intermediate’s certificate, signed by the root.
  3. The root’s certificate, already in your browser’s list. The server doesn’t need to send it.

Notice this is a second key pair with a different job. The key-exchange keys are made fresh for every connection and only make the shared secret. The certificate’s key pair lasts for months and is only used to sign, to prove who is speaking. It never helps make the secret, which is why stealing it later can’t unlock old recordings.

In TLS 1.3, the current version, the certificate already travels encrypted with the new secret. That hides it from the café, but proves nothing yet. When it arrives, the browser makes four checks. Any failure and it stops:

  1. The name in the certificate matches the site you typed.
  2. Today falls between its start and end dates.
  3. Each signature checks out with the public key one level up, ending at a root in the trusted list.
  4. The server signs the handshake so far with the certificate’s private key, and that signature checks out with the public key in the certificate.
Guess first: shop.example’s certificate is public: every visitor receives a copy. What stops the laptop at the next table from simply sending that copy?

Check 4. A copy of the certificate contains only the public key. To pass, the server must sign this handshake, which includes your browser’s fresh public key, with the matching private key. That private key never leaves shop.example’s servers, so the copy is worthless. In the demo, pick Copied certificate: the first three checks pass and the fourth fails.

Log in on café Wi-Fi

  1. Start on HTTP and change the password. The panel “Someone recording the café Wi-Fi sees” shows it in red, along with the page and the cookie.
  2. Press HTTPS, then Next step. At step 2, compare the secret on both sides: the same 32 bytes, made by your browser, never sent. Press New keys and both change together.
  3. Pick Copied certificate, Wrong name or Fake root (this takes you back to step 1). At step 2 the secret still matches: you agreed it with the attacker. At step 3 one check fails, the browser stops and Next step is disabled.
  4. Pick Real server and go to step 5. The eavesdropper’s panel shows the site name, the address, the public keys and scrambled bytes, with page, cookie and password hidden. Add 5 letters to the password and watch the size.

Trip two: the same password, sealed

With all four checks passed, both sides feed the shared secret, together with the hellos, through a mixing function to make two keys: a 16-byte one for encrypting, and one for making the Finished code. Each also sends a Finished message, a short code made from the secret and every byte of the hellos. Only someone holding the secret can make it. Your first hello listed the ciphers (encryption methods) your browser supports. If anyone had edited the hellos, say by deleting the strongest ciphers to force a weak one, the codes would not match and the connection would close.

Now your 185-byte request is encrypted with AES-GCM, the cipher most HTTPS traffic uses. Encryption doesn’t change the length. TLS then adds 22 bytes: a 5-byte header saying “encrypted data, this long”, 1 byte saying the contents are request data rather than a handshake message, and a 16-byte tag. The tag is a checksum only the key holder can make: if any byte is changed on the way, the server’s check fails and it refuses the data. So a 207-byte record crosses the café.

The server holds the same secret, so it makes the same key and gets your exact 185 bytes back. The password, the page /login and the cookie are all inside the sealed part.

What the next table still sees

HTTPS hides what you say, not that you said it. Here is what the eavesdropper gets each time:

HTTPHTTPS
Server’s IP address and portYesYes
Site name, shop.exampleYesYes, from SNI
Page (/login), headers, cookiesYesNo
Password and everything in the bodyYesNo
How many bytes, and whenYesYes
Can change what you receive unnoticedYesNo

The site name leaks because of SNI (Server Name Indication), a field in your browser’s first hello. One server often hosts hundreds of sites on one IP address, so it needs the name to pick which certificate to send, and at that moment nothing is encrypted yet. A newer extension, Encrypted Client Hello, hides it, but few sites turn it on yet.

Guess first: You make the password 5 letters longer. What does the eavesdropper notice?

The request grows by exactly 5 bytes, 207 to 212. The eavesdropper can’t read the password, but it learns its length. Sizes and timing leak more than you might think: the size of a response can reveal which page or picture you loaded. Try it at step 5 of the demo.

The first visit is the weak spot

When you type shop.example with no https://, older browsers send the first request over plain HTTP and get redirected, and newer ones still fall back to HTTP if HTTPS fails. That first request is unprotected, and the fake hotspot can answer it and simply keep you on HTTP. You would see no error, only a missing padlock.

HSTS (HTTP Strict Transport Security) closes this. The site sends the header Strict-Transport-Security: max-age=31536000, and the browser then refuses plain HTTP for that site for a year (31,536,000 seconds). Sites can also ask to be on a list built into Chrome and Firefox, so even the very first visit uses HTTPS.

What the padlock costs

The TCP concept walks through the handshake that opens every connection. TLS adds its own on top, so a new HTTPS connection pays both before your request can leave. With a server 40 ms away and back (one round trip):

ConnectionRound trips before the request leavesWait at 40 ms each
Plain HTTP1 (TCP)40 ms
HTTPS, TLS 1.3, first visit2 (TCP + TLS)80 ms
HTTPS, TLS 1.2, first visit3 (TCP + 2 for TLS)120 ms
HTTPS, TLS 1.3, returning (0-RTT: zero round trips for TLS)1 (TCP only)40 ms

TLS 1.3 needs one round trip because your browser guesses the key method and sends its public key in the very first hello. The server replies with its hello, certificate and Finished in one go. TLS 1.2 needed an extra round trip to agree on the method first.

On a return visit, TLS 1.3 can resume: both sides remember a key from last time, so the browser sends the request inside its first hello, zero extra round trips. The catch: a normal connection mixes in fresh keys from both sides, so a recorded message is useless in a new one. The 0-RTT request goes out before the server adds anything fresh, so an eavesdropper can record it and send it again, and the server can’t tell the copy from the original. So servers only accept it for requests that are safe to repeat, like loading a page, never a login or a payment.

The encryption itself is cheap. Modern CPUs have AES built into their instructions and encrypt gigabytes a second per core. The cost that matters is the round trips, which is why browsers, load balancers and database drivers keep connections open and reuse them.

Reading the padlock

You can now say exactly what the padlock next to shop.example means. Your browser agreed a fresh secret in front of the whole café. A chain of signatures from a root it already trusted vouched for the name. The server proved it holds the private key. And every byte since then is encrypted and checked for changes.

You can also say what it doesn’t mean. It doesn’t mean the site is honest: a scam site can get a perfectly valid certificate for its own name, which is the Wrong name case seen from the other side. And it doesn’t hide which site you visited, how much you sent or when.

In a system design, this decides three things:

  • Where HTTPS ends. Usually at the load balancer, which must decrypt to read the path, for example to send /api and /images to different servers. Then you choose whether to encrypt again for the hop to your app servers.
  • How certificates renew. Since March 2026 a CA may issue one for at most 200 days, falling to 47 days by 2029, so renewal must be automatic.
  • How long connections live. Keep them open and reuse them, so the handshake is paid once, not on every request.

Remember

  • Plain HTTP on shared Wi-Fi: anyone nearby reads and can change every byte, password included.
  • Key exchange lets two strangers agree a secret in public: easy forwards, hopeless backwards.
  • A certificate is a CA-signed “this key belongs to this name”; the server proves it holds the private key.
  • HTTPS hides the page, headers and body, but not the site name (SNI), sizes or timing.
  • TLS 1.3 costs one extra round trip on a new connection, zero when resuming; reuse connections.

See it in a design

  • Payment system with ledger: Idempotent payments API, processor routing and an append-only double-entry ledger.
  • Flash sale: Limited drop that sells from an atomic Redis counter and writes orders through a queue.

Further reading and videos