Field note / fundamentals

publishedupdated 2026-05-01#https#tls#security#encryption#certificates

How HTTPS Works (TLS Handshake)

TLS 1.3 handshake step-by-step — asymmetric vs symmetric encryption, certificate validation, session keys, and why HTTPS is fast.

Overview

HTTPS = HTTP + TLS (Transport Layer Security). TLS provides:

  • Confidentiality — data encrypted in transit
  • Integrity — data not modified in transit (MAC)
  • Authentication — server is who it claims to be (certificates)

The core insight: TLS uses asymmetric encryption (RSA/ECDHE) only for the handshake — to securely exchange a symmetric session key. All actual data transfer uses the cheaper symmetric key (AES).


Architecture

 TLS 1.3 Handshake (1-RTT)
 ════════════════════════════════════════════════════════════

  Client                                          Server
    │                                               │
    │── ClientHello ──────────────────────────────▶│
    │   - TLS version: 1.3                          │
    │   - Supported cipher suites                   │
    │   - Client random nonce                       │
    │   - Key share (Diffie-Hellman public key)     │
    │                                               │
    │◀─ ServerHello ─────────────────────────────── │
    │   - Chosen cipher suite                       │
    │   - Server random nonce                       │
    │   - Key share (DH public key)                 │
    │                                               │
    │◀─ Certificate ──────────────────────────────  │
    │   - Server's public key                       │
    │   - Signed by trusted CA (e.g., DigiCert)    │
    │                                               │
    │◀─ CertificateVerify ─────────────────────── │
    │   - Signature proving server owns private key │
    │                                               │
    │◀─ Finished (encrypted) ───────────────────── │
    │                                               │
    │  [Client validates certificate chain]         │
    │  [Both sides derive session keys from DH]     │
    │                                               │
    │── Finished (encrypted) ────────────────────▶ │
    │                                               │
    │══ All subsequent data encrypted with AES ════│

 Key Derivation (ECDHE):
 ─────────────────────────────────────────────────
  Client private key + Server public key
  Server private key + Client public key
  → Both compute the SAME shared secret (math magic)
  → Session key derived from shared secret + nonces
  → Attacker who sees the traffic CANNOT derive it
    (even if they later get server's private key — Forward Secrecy)

 Certificate Chain Validation:
 ─────────────────────────────────────────────────
  Server cert ──▶ Intermediate CA ──▶ Root CA
  (signed by)     (signed by)        (trusted by OS/browser)

Technical Implementation

TLS Certificate Setup (nginx)

server {
    listen 443 ssl;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # TLS versions — disable TLS 1.0/1.1 (deprecated)
    ssl_protocols TLSv1.2 TLSv1.3;

    # Prefer server cipher order, modern ciphers only
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;  # TLS 1.3 handles this itself

    # Session resumption — skip handshake for returning clients
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    # HSTS — tell browsers to always use HTTPS
    add_header Strict-Transport-Security "max-age=63072000" always;

    # OCSP stapling — faster certificate revocation check
    ssl_stapling on;
    ssl_stapling_verify on;
}

Inspecting TLS Handshake (curl)

# See full TLS handshake details
curl -v --tlsv1.3 https://example.com 2>&1 | grep -A 20 "SSL connection"

# Check certificate details
openssl s_client -connect example.com:443 -servername example.com

# Output shows:
# Certificate chain
# Subject: CN=example.com
# Issuer: CN=DigiCert TLS RSA SHA256 2020 CA1
# Validity: Not Before/After
# Cipher: TLS_AES_256_GCM_SHA384 (TLS 1.3)

Self-Signed Cert for Dev (Node.js)

import https from 'https';
import fs from 'fs';

const server = https.createServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.cert'),
  // Force TLS 1.3
  minVersion: 'TLSv1.3',
}, (req, res) => {
  res.writeHead(200);
  res.end('Secure!');
});

server.listen(443);

Why Asymmetric for Handshake, Symmetric for Data?

Asymmetric (RSA/ECDHE):
  + Can exchange keys securely over an insecure channel
  - 1000x slower than symmetric — CPU-intensive math
  - Cannot encrypt arbitrary-length data efficiently
  - Used ONLY for the handshake

Symmetric (AES-256-GCM):
  + 10GB/s throughput on modern hardware (AES-NI instruction)
  + Fixed computation time regardless of key size
  - Cannot securely exchange the key without a secure channel
  - Used for ALL actual HTTP data

The genius of TLS: use asymmetric to establish a shared secret,
then switch to symmetric for everything else.

Interview Preparation

Q: Why does TLS use both asymmetric and symmetric encryption?

Asymmetric encryption (RSA, ECDHE) solves the key exchange problem — two parties can establish a shared secret over an insecure channel without ever having met. But it's ~1000x slower than symmetric encryption and can't efficiently encrypt large data. So TLS uses asymmetric only for the handshake, derives a symmetric session key, then encrypts all HTTP data with AES. Best of both worlds.

Q: What is Forward Secrecy and why does it matter?

Forward Secrecy (Perfect Forward Secrecy / PFS) means that compromising the server's private key today cannot decrypt recorded past traffic. TLS 1.3 enforces PFS by using ephemeral Diffie-Hellman (ECDHE) — each session generates a fresh key pair that's discarded after the session. Even if someone recorded 5 years of encrypted traffic and then stole your private key, they still can't decrypt it.

Q: What is a Certificate Authority (CA) and why do we trust them?

A CA is a third party that cryptographically signs your certificate, vouching that you own the domain. Browsers/OS ship with a list of ~100 trusted root CAs (Mozilla, DigiCert, etc.). When a server presents a certificate, the browser checks if it's signed (directly or through intermediaries) by a trusted root CA. If the chain of signatures is valid → trust the certificate.

Q: What does HSTS do?

HTTP Strict Transport Security (HSTS) tells browsers to never make an HTTP connection to this domain again — always use HTTPS. Prevents SSL stripping attacks where an attacker downgrades HTTPS to HTTP. Once a browser sees the Strict-Transport-Security header, it enforces HTTPS for max-age seconds, even if the user types http://.

Q: What's the difference between TLS 1.2 and TLS 1.3?

TLS 1.3: reduced handshake to 1-RTT (vs 2-RTT in 1.2), removed weak cipher suites (RSA key exchange, RC4, SHA-1), enforced forward secrecy for all sessions, added 0-RTT session resumption (with some caveats around replay attacks). TLS 1.2 is still widely used but should be considered legacy.


Learning Resources