← Computer Networks
DNS & the Web Application Layer

HTTPS & TLS

Watch: "SSL, TLS, HTTP, HTTPS Explained" — PowerCert Animated Videos

HTTPS is just HTTP layered over TLS, but the handshake underneath is what gives you confidentiality, integrity, and server authenticity — the non-negotiable baseline for any production API. Interviewers use this topic to check whether you understand what TLS termination actually buys and costs a system. The stack is HTTP → TLS → TCP → IP: TLS is a session layer sitting between the reliable byte stream TCP gives you and the HTTP semantics riding on top of it.

What Is HTTPS?

HTTPS is the secure version of HTTP — the same request-and-response conversation between your browser and a website, but wrapped in encryption so nobody in between (your Wi-Fi provider, a hacker on the same network, your ISP) can read or tamper with what's being sent. The padlock icon in your browser's address bar means you're on HTTPS.

What Is TLS?

TLS (Transport Layer Security) is the actual technology that does the encrypting — it's the "S" in HTTPS. Before any data is exchanged, your browser and the website perform a quick handshake to agree on a secret code only the two of them know, and to confirm the website is really who it claims to be, not an impostor.

Where This Is Used

A Day-to-Day Example

Imagine mailing a letter in a locked box instead of a plain envelope. Anyone who intercepts the box in transit — a nosy mail carrier, someone rifling through the mailroom — sees only a sealed box, not the letter inside. TLS is the process of you and the recipient agreeing on a key for that lock before anything is sent, and checking each other's ID first so you know the box is really going to the right person.

Deep Dive: Certificate Chain & Validation

A certificate binds a public key to an identity — a domain name — and is signed by a Certificate Authority. Trust is a chain, not a single signature:

Certificate chain from root to leafRoot CApre-installed in OS / browser, self-signedIntermediate CAsigned by the rootexample.com (leaf)signed by the intermediatesignssignsserver sends leaf +intermediate; browserchecks up to a root
Trust flows down the chain: the browser already trusts the root, the root vouches for the intermediate, and the intermediate vouches for the site's certificate. Validation checks every signature, the dates, and that the leaf's name matches the domain.
trust anchorsite certificate
Show text version
Root CA (pre-installed in OS/browser trust store, self-signed)
   └── Intermediate CA (signed by Root CA)
         └── Leaf certificate for example.com (signed by Intermediate CA)

When the client receives the server's certificate chain, it walks it upward: does the leaf's signature verify against the intermediate's public key? Does the intermediate's signature verify against a root the client already trusts? It also checks the leaf's Subject Alternative Name (SAN) field against the hostname it's connecting to, and checks the certificate hasn't expired or been revoked (via OCSP or a CRL). Root CAs are never sent over the wire — the client already has them locally; only the leaf and intermediate(s) are sent by the server, which is why a misconfigured server that forgets to send the intermediate certificate produces "works in Chrome, fails in curl/some clients" — different trust stores handle a missing intermediate differently.

Deep Dive: The TLS 1.3 Handshake

TLS 1.3 handshakeClientServerClientHellociphers, key share, SNIServerHellochosen cipher, key share{Certificate, Verify, Finished}already encrypted{Finished}application data, encrypted both ways
Both sides send a key share in their first message, so after one round trip they already share a secret and everything after ServerHello (including the certificate) is encrypted. Braces mean encrypted.
clientserver
Show text version
Client                                                      Server
  |-- ClientHello (supported ciphers, key_share, SNI) ------>|
  |<-- ServerHello (chosen cipher, key_share) ----------------|
  |<-- {Certificate, CertificateVerify, Finished} (encrypted)-|
  |-- {Finished} (encrypted) -------------------------------->|
  |======= Application Data (encrypted, both directions) ====|

Both sides send a key share in the very first two messages (an ephemeral Diffie-Hellman, ECDHE) and can derive the shared symmetric secret immediately after — that's what makes TLS 1.3 a 1-RTT handshake: encrypted application data can flow after just one round trip, versus TLS 1.2's 2-RTT (cipher negotiation and key exchange were separate round trips in 1.2). TLS 1.3 also supports 0-RTT resumption: on a repeat connection to a server you've talked to recently, the client can send encrypted application data in its very first flight, using a pre-shared key from the prior session — zero round trips before data flows. The trade-off is real: 0-RTT data has no forward-secrecy protection against replay — an attacker who captures that first flight can resend it, so 0-RTT is only considered safe for idempotent requests (GET), never for something like a payment POST.

Deep Dive: Symmetric vs Asymmetric Roles

Asymmetric crypto (RSA or ECDSA for signing, ECDHE for key exchange) is computationally expensive, so TLS uses it only for two narrow jobs: authenticating the server (the certificate's signature) and establishing a shared secret (the key exchange). Once that shared secret exists, both sides switch to a fast symmetric cipher — AES-GCM or ChaCha20-Poly1305 — to actually encrypt the request/response bytes flowing back and forth. This split exists purely for performance: symmetric encryption is orders of magnitude cheaper per byte than asymmetric, but asymmetric crypto is the only piece that lets two parties who've never met agree on a secret over a public channel without an eavesdropper deriving it.

Key Pointers

How It Works

  1. Client sends a ClientHello with supported cipher suites and a key share.
  2. Server responds with a ServerHello, its certificate chain, and its own key share.
  3. Both sides independently derive the same symmetric session key via an ephemeral Diffie-Hellman exchange (ECDHE) — the secret itself is never transmitted.
  4. The client validates the certificate chain up to a trusted root CA and checks that the hostname matches.
  5. Both sides exchange Finished messages to confirm handshake integrity, then switch to encrypted application data.

Try It Yourself

# Inspect the full handshake and certificate chain from the command line
openssl s_client -connect example.com:443 -servername example.com

# Same, but print only the certificate chain details
openssl s_client -connect example.com:443 -servername example.com -showcerts

# curl's verbose mode shows the negotiated TLS version and cipher suite
curl -v https://example.com 2>&1 | grep -i "SSL\|TLS"

# In Chrome DevTools: click the padlock icon → Connection is secure → Certificate is valid
# Security tab shows negotiated protocol (e.g. TLS 1.3) and cipher suite directly

# Check certificate expiry programmatically
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

Interview Q&A

Q: What does HTTPS actually protect against?

A: Confidentiality — a network observer can't read the contents of the request or response. Integrity — any tampering with the data in transit is detectable and causes the connection to fail rather than silently deliver corrupted data. Server authentication — successful certificate validation proves you're actually talking to the server that controls the private key for that domain, not an impostor.

Q follow-up: Does that mean HTTPS protects the data once it reaches the server?

A: No — TLS only protects data in transit, on the wire between client and server. Once the server decrypts it, TLS has nothing to say about what happens next: how it's stored, logged, or authorized internally is entirely the application's responsibility. This is a common follow-up specifically because candidates conflate "encrypted in transit" with "secure everywhere."

Q: Why does TLS 1.3 need fewer round trips than TLS 1.2?

A: TLS 1.2 negotiated the cipher suite and performed the key exchange as effectively separate round trips before any application data could flow, making it 2-RTT. TLS 1.3 simplified and reordered the handshake so the client sends its key share in the very first message alongside its hello, letting the server respond with everything needed — including encrypted certificate and Finished messages — in one flight, cutting it to 1-RTT.

Q follow-up: What about 0-RTT — is it strictly better?

A: No, it trades away replay protection. 0-RTT lets a returning client send encrypted application data in its first flight using a resumed pre-shared key, before the handshake fully completes — but because there's no fresh randomness exchanged yet on the server side, an attacker who intercepts that first flight can replay it and the server has no built-in way to tell it apart from the original. That's why 0-RTT is generally restricted to idempotent, side-effect-free requests.

Q: What's the actual difference between what a firewall and TLS each protect against?

A: They're not overlapping controls. TLS protects the confidentiality/integrity/authenticity of one connection's data in transit. A firewall controls which connections are allowed to reach a host at all, based on IP/port/protocol — it has no visibility into TLS-encrypted payloads and can't stop, say, someone from reading your traffic if TLS itself is broken or misconfigured.

System Design Tie-in

TLS termination placement is a design decision interviewers expect you to justify, not just name. Terminating at a CDN/load balancer edge offloads CPU-heavy crypto from your backend fleet and centralizes certificate management, but means you're trusting your internal network for whatever hop comes next — plaintext internally, or re-encrypted with internal certificates (common in a zero-trust or PCI-compliance context where "trust the internal network" isn't an acceptable answer). For anything handling payments or health data, expect to be asked about mTLS between internal services, where both sides present certificates and authenticate each other — not just the client authenticating the server. Certificate expiry is also worth volunteering as an operational risk: it's a disproportionately common real-world outage cause, and the correct answer is automating renewal (ACME/Let's Encrypt or an internal equivalent) rather than tracking expiry dates manually.

Trade-offs

Where TLS terminates is a real design decision: terminating at the edge (CDN/load balancer) offloads CPU-heavy crypto from backend services but requires trusting the internal network for any plaintext hop; end-to-end TLS to every service limits the blast radius of a compromised internal hop but adds CPU cost and certificate management at every node. Certificate expiry is a disproportionately common cause of production outages — automate renewal (e.g. ACME/Let's Encrypt) rather than tracking it manually. A frequent interview correction: TLS authenticates the server (and optionally the client via mTLS) and encrypts the channel, but it says nothing about what the application does with the data once decrypted — it's not a substitute for application-layer authorization.