Skip to main content

TLS & HTTPS

Plain HTTP sends everything in the clear: anyone on the path can read or alter it. HTTPS is just HTTP running inside TLS (Transport Layer Security), the protocol that adds confidentiality, integrity, and authentication to a TCP connection. Before any web request or response travels, TLS runs a handshake to agree on keys and prove the server's identity.

Step through a TLS 1.3 handshake and watch the channel go from open to encrypted:

handshake messagelocal computationencrypted (secure channel)
🔓 handshake in the clear
Client
Server
ClientHello + key share
Client proposes cipher suites and sends its ephemeral (Diffie-Hellman) public key share.
handshakingstep 0 / 6

The TLS 1.3 handshake

TLS 1.3 establishes a secure channel in a single round trip:

  1. ClientHello + key share - the client proposes cipher suites and sends its ephemeral (Diffie-Hellman) public key share.
  2. ServerHello + certificate + key share - the server picks a cipher suite, sends its certificate, and sends its own ephemeral key share.
  3. Both derive session keys - each side combines the two key shares into the same shared secret. The eavesdropper saw both public shares but still cannot compute the secret.
  4. Encrypted application data - HTTP requests and responses now flow, fully encrypted with the symmetric session keys.

This is the hybrid pattern from the cryptography lesson: public-key math to agree on a key, fast symmetric encryption for the data.

TLS 1.3's 1-RTT vs TLS 1.2's 2-RTT, in milliseconds

TLS 1.2 needed a full 2 round trips before any application data could flow: one round trip to negotiate the cipher suite and exchange random values, then a second to exchange keys and finish the handshake. TLS 1.3 collapses that to 1 round trip because the client sends its key share in the very first message, guessing which parameters the server will accept.

Say the client and server are 40 ms apart (roughly a cross-country round trip):

  • TCP handshake: 1 RTT = 40 ms, before TLS even starts.
  • TLS 1.2: 2 more RTTs = 80 ms. Total before the first HTTP byte: 120 ms.
  • TLS 1.3: 1 more RTT = 40 ms. Total before the first HTTP byte: 80 ms.
  • TLS 1.3 with 0-RTT (session resumption): the client can send encrypted application data in its very first flight, riding along with the TCP handshake in some deployments - 0 extra RTTs for a returning client, though 0-RTT data is replayable and typically restricted to idempotent requests for that reason.

That is a third of the pre-data latency shaved off a fresh connection just by the protocol version, before a single byte of the actual page has been requested - and it is why TLS 1.3 adoption mattered so much for page-load speed on mobile networks where a single RTT can be 100 ms or more.

Verifying the certificate

The server's certificate binds its public key to its domain name, signed by a CA. The client checks it against its trusted root CAs (the chain of trust) before deriving keys. If the certificate is expired, self-signed, or issued for the wrong domain, the browser refuses to continue - this is what stops an attacker from impersonating a site.

Clock skew can fail certificate validation with a perfectly valid certificate

Certificate validation checks the current time against the certificate's notBefore and notAfter fields - and that check uses the client's own clock, not a trusted external source. A device whose clock has drifted (a dead CMOS battery, a container that booted with the wrong system time, a misconfigured NTP client) can see a completely valid, unexpired certificate and reject it as "not yet valid" or "expired" anyway, because from that device's point of view the certificate's validity window is in the future or the past. This is a recurring real-world failure mode for embedded devices, freshly-provisioned VMs and containers that start before NTP has synced, and CI runners with a stale hardware clock - the fix is always the same: make sure the clock is correct (NTP) before trusting any certificate, since TLS has no way to tell "the cert is bad" apart from "my clock is wrong."

Forward secrecy

TLS 1.3 uses ephemeral key shares: fresh Diffie-Hellman keys generated for this connection and thrown away afterward. Because the session key is never sent on the wire and the ephemeral private keys are discarded, an attacker who records the traffic today and later steals the server's long-term private key still cannot decrypt past sessions. This property is called forward secrecy.

info

HTTPS is HTTP over TLS. It adds confidentiality (traffic is encrypted), integrity (tampering is detected), and authentication (the certificate proves you are talking to the real server). None of these exist in plain HTTP.