Intro to HTTPS & SSL/TLS

Intro to HTTPS & SSL/TLS

That little padlock icon in your browser's address bar represents one of the most important security innovations on the internet. Let's understand what it actually means — and what happens under the hood.


1. HTTP vs HTTPS — The Core Difference

HTTP (Hypertext Transfer Protocol):
  Client ──── [username=alice&password=secret123] ──────► Server
                     ↑
               Plain text! Anyone who intercepts this network traffic can read it.

HTTPS (HTTP Secure):
  Client ──── [x7k#9Lp@2!Qr5vN3mZ8...] ──────────────► Server
                     ↑
               Ciphertext! Completely unreadable without the decryption key.

HTTPS is simply HTTP running inside an encrypted TLS tunnel. The HTTP protocol itself doesn't change — only the transport layer changes.


2. Why HTTPS Matters

ThreatHTTPHTTPS
Password theft on public Wi-Fi❌ Vulnerable✅ Protected
Man-in-the-middle interception❌ Vulnerable✅ Protected
Content injection (ads/malware by ISP)❌ Vulnerable✅ Protected
Forged responses❌ Vulnerable✅ Protected
Search Engine rankingPenalised✅ Boosted
Browser warnings ("Not Secure")❌ Shown✅ Not shown
HTTP/2 support❌ (in practice)✅ Required

HTTPS provides three guarantees:

  1. Confidentiality — only the intended recipient can read the data
  2. Integrity — data cannot be modified in transit without detection
  3. Authentication — you know you're talking to the real server, not an impersonator

3. SSL vs TLS — What's the Difference?

ProtocolYearStatus
SSL 1.0Never releasedAbandoned
SSL 2.01995Deprecated (broken)
SSL 3.01996Deprecated (POODLE attack)
TLS 1.01999Deprecated (2020)
TLS 1.12006Deprecated (2020)
TLS 1.22008🟡 Still widely used
TLS 1.32018✅ Current standard

The terms "SSL" and "TLS" are often used interchangeably in conversation, but SSL is dead — all modern HTTPS uses TLS 1.2 or 1.3. When people say "SSL certificate," they mean a TLS certificate.

TLS 1.3 improvements over 1.2:

  • 0-RTT (zero round-trip resumption) — faster reconnections
  • Fewer cipher suites (simpler, more secure)
  • Shorter handshake (1 round-trip instead of 2)
  • Forward secrecy is mandatory

4. How TLS Works: The Handshake

Before any HTTP data is sent, the client and server perform a TLS handshake to agree on encryption parameters and authenticate the server.

TLS 1.3 Handshake (simplified):

Client                              Server
  │                                    │
  │── ClientHello ───────────────────►│
  │   (supported TLS versions,          │
  │    cipher suites, key exchange)     │
  │                                    │
  │◄── ServerHello ────────────────────│
  │    Certificate (identity proof)     │
  │    ServerFinished (encrypted)       │
  │                                    │
  │  [Client verifies certificate]     │
  │  [Both compute shared secret]      │
  │                                    │
  │── ClientFinished (encrypted) ────►│
  │                                    │
  │  [TLS tunnel established]          │
  │                                    │
  │── GET /dashboard HTTP/2 ─────────►│  ← All HTTP traffic now encrypted
  │◄── HTTP/2 200 OK ──────────────────│

The whole handshake typically takes 50–150ms on the first connection. Subsequent connections can reuse the session (session resumption) and complete in as little as 0ms additional overhead (0-RTT).


5. Symmetric vs Asymmetric Encryption

TLS uses both types of encryption:

Asymmetric Encryption (Public-Key Cryptography)

Used during the handshake to securely exchange keys.

Server has:
  Private key (🔑 kept secret on the server)
  Public key  (🔓 shared with everyone via the certificate)

Encryption with public key → only private key can decrypt
Signature with private key → anyone with public key can verify

Example:
  Alice encrypts a secret with Bob's 🔓 public key
  → Only Bob's 🔑 private key can decrypt it
  → Even Alice can't decrypt it after encrypting!

Symmetric Encryption (Shared Secret)

Used for all actual data transfer — much faster than asymmetric.

After the handshake, both sides share a secret key:
  Client encrypts with secret key ──────────────────►
  ◄────────────────── Server decrypts with same secret key

AES-256 is a common symmetric cipher used in TLS.

The handshake uses asymmetric crypto to securely agree on a symmetric key, then all HTTP data is encrypted with that fast symmetric key.


6. Cipher Suites

A cipher suite is a combination of algorithms used for key exchange, authentication, encryption, and message authentication.

TLS_AES_256_GCM_SHA384
    │    │    │    │
    │    │    │    └── Message authentication (hash function)
    │    │    └─────── Encryption mode (operation mode)
    │    └──────────── Encryption algorithm (256-bit AES)
    └───────────────── TLS version prefix

TLS 1.3 reduces to three safe cipher suites (down from hundreds in TLS 1.2):

  • TLS_AES_256_GCM_SHA384
  • TLS_AES_128_GCM_SHA256
  • TLS_CHACHA20_POLY1305_SHA256

7. Forward Secrecy

Forward secrecy (or Perfect Forward Secrecy — PFS) means that if an attacker records encrypted traffic today and later steals the server's private key, they still cannot decrypt the recorded traffic.

This works by using ephemeral session keys (generated fresh for each session and discarded after). TLS 1.3 mandates forward secrecy.

Without Forward Secrecy:
  Attacker records encrypted traffic
  Later compromises server's private key
  → Can decrypt all old recorded traffic ❌

With Forward Secrecy (TLS 1.3):
  Each session uses a temporary key (ephemeral Diffie-Hellman)
  Server's private key never directly encrypts session data
  Even with the private key, old sessions cannot be decrypted ✅

8. HTTPS in Practice

Always Use HTTPS in Code

// ✅ Secure — data travels through encrypted TLS tunnel
const response = await fetch('https://api.nandhoo.com/profile');

// ❌ Insecure — data travels in plain text
const response = await fetch('http://api.nandhoo.com/profile');

HTTP Strict Transport Security (HSTS)

HSTS tells the browser to always use HTTPS for this domain, even if the user types just nandhoo.com:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
                               │                 │              │
                               │                 │              └── Submit to HSTS preload list
                               │                 └────────────────── Also apply to subdomains
                               └──────────────────────────────────── Cache for 1 year

Mixed Content

Mixing HTTP and HTTPS on the same page creates mixed content errors:

<!-- On an HTTPS page: -->

<!-- ✅ Secure — subresource also uses HTTPS -->
<img src="https://cdn.nandhoo.com/logo.png">

<!-- ❌ Blocked — browser blocks HTTP resources on HTTPS pages -->
<img src="http://old-cdn.nandhoo.com/logo.png">

9. Getting an HTTPS Certificate

Step 1: Generate a Key Pair

# Generate private key
openssl genrsa -out private.key 2048

# Generate Certificate Signing Request (CSR)
openssl req -new -key private.key -out request.csr

Step 2: Get it Signed by a CA

Option A — Let's Encrypt (Free, Automated)

# Install certbot
brew install certbot

# Issue a certificate (verifies domain ownership automatically)
certbot certonly --standalone -d nandhoo.com -d www.nandhoo.com

# Auto-renew every 90 days
certbot renew --quiet

Option B — Paid CA (DigiCert, Sectigo, etc.) Submit the CSR to the CA, complete domain validation, receive the signed certificate.

Step 3: Configure Your Server

# nginx configuration
server {
    listen 443 ssl http2;
    server_name nandhoo.com;

    ssl_certificate     /etc/letsencrypt/live/nandhoo.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/nandhoo.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers   ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location / {
        proxy_pass http://localhost:3000;
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    return 301 https://$host$request_uri;
}

10. Checking a Site's TLS Configuration

# Check TLS version and certificate details
openssl s_client -connect nandhoo.com:443 -brief

# Check supported TLS versions (using testssl.sh)
docker run --rm drwetter/testssl.sh nandhoo.com

# Online tool (no install needed)
# https://www.ssllabs.com/ssltest/

In your browser:

  1. Click the padlock in the address bar
  2. Click Connection is secure
  3. Click Certificate is valid
  4. See: issuer, expiry date, and the algorithm used

11. Common Mistakes

MistakeProblemFix
Using HTTP in productionData exposed in plaintextMove all traffic to HTTPS
Not redirecting HTTP to HTTPSUsers who type domain without https get HTTP301 redirect all HTTP to HTTPS
Not setting HSTSBrowser still allows HTTP on first visitAdd Strict-Transport-Security header
Mixed contentBrowser blocks HTTP resources on HTTPS pagesUse protocol-relative URLs or explicit HTTPS
Not renewing certificatesSite shows "Not Secure" after expiryUse Let's Encrypt with auto-renewal
Serving outdated TLS 1.0/1.1Vulnerable to known attacksDisable TLS 1.0 and 1.1; only allow 1.2+

12. Mini Exercises

  1. Open any popular website and inspect the TLS details in the padlock icon. What TLS version does it use? What is the certificate's expiry date?
  2. Visit SSL Labs and test any public website. What grade does it receive?
  3. Find a website that still serves pages over plain HTTP. What does your browser display in the address bar?
  4. In DevTools → Security tab, check if any mixed content is being blocked on an HTTPS page.
  5. Look up what "HSTS Preload" means. How would a domain get added to a browser's HSTS preload list?