HTTP (HyperText Transfer Protocol) is the foundation of data communication on the World Wide Web. It defines how messages are formatted and transmitted between web browsers (clients) and web servers.
Default Port: 80 (unencrypted)
URL Format: http://example.com
HTTP follows a request-response model:
Browser (Client) Web Server ┌──────────────────┐ ┌──────────────────┐ │ │ 1. HTTP Request │ │ │ http:// │──────────────────────────>│ Port 80 │ │ example.com │ GET /page.html HTTP/1.1 │ │ │ │ Host: example.com │ │ │ │ │ │ │ │ 2. HTTP Response │ │ │ │<──────────────────────────│ │ │ Renders page │ HTTP/1.1 200 OK │ Sends HTML │ │ │ Content-Type: text/html │ │ │ │ ... │ │ └──────────────────┘ └──────────────────┘ ⚠️ All data transmitted in PLAIN TEXT - readable by anyone intercepting!
HTTPS (HTTP Secure) is HTTP with TLS/SSL encryption added. All communication between client and server is encrypted, preventing eavesdropping and tampering.
Default Port: 443 (encrypted)
URL Format: https://example.com
Security: TLS (Transport Layer Security) encryption
Browser (Client) Web Server ┌──────────────────┐ ┌──────────────────┐ │ │ 1. TLS Handshake │ │ │ https:// │<─────────────────────────>│ Port 443 │ │ example.com │ Exchange keys │ + SSL Cert │ │ │ Verify certificate │ │ │ │ │ │ │ │ 2. Encrypted Request │ │ │ 🔒 Encrypted │──────────────────────────>│ 🔒 Decrypts │ │ │ [encrypted gibberish] │ │ │ │ │ │ │ │ 3. Encrypted Response │ │ │ 🔓 Decrypts │<──────────────────────────│ 🔒 Encrypts │ │ Renders page │ [encrypted gibberish] │ │ └──────────────────┘ └──────────────────┘ ✅ Data is ENCRYPTED - unreadable to anyone intercepting!
| Feature | HTTP | HTTPS |
|---|---|---|
| Encryption | ❌ None | ✅ TLS/SSL |
| Default Port | 80 | 443 |
| Certificate Required | ❌ No | ✅ Yes |
| Data Privacy | ❌ Readable | ✅ Encrypted |
| Identity Verification | ❌ None | ✅ CA-verified |
| Browser Trust Indicator | "Not Secure" warning | Padlock icon 🔒 |
| SEO Ranking | Lower | Higher (Google boost) |
| Service Workers | ❌ Not allowed | ✅ Allowed |
| Geolocation API | ❌ Blocked (except localhost) | ✅ Allowed |
| Performance | ~1-2% faster | HTTP/2 often faster overall |
HTTPS uses TLS (Transport Layer Security), formerly known as SSL (Secure Sockets Layer). The process involves two types of encryption:
Used for the initial key exchange. Slow but secure for establishing connection.
Used for the actual data transfer. Fast and efficient for bulk data.
Browser connects to https://example.com:443 and says:
Server responds with:
Browser checks certificate:
If any check fails → 🔴 Connection blocked, security warning shown
Browser generates a session key for symmetric encryption:
All subsequent HTTP traffic is encrypted with the session key:
An SSL/TLS certificate is a digital document that proves a website's identity and contains the public key needed for encryption.
Certificate:
Data:
Version: 3
Serial Number: a3:47:b1:c4:2e:...
Issuer: C=US, O=Let's Encrypt, CN=R3
Validity:
Not Before: Dec 1 00:00:00 2025 GMT
Not After : Mar 1 23:59:59 2026 GMT
Subject: CN=example.com
Subject Public Key Info:
Public Key Algorithm: RSA (2048 bit)
Public Key: 30:82:01:0a:...
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com
Signature Algorithm: sha256WithRSAEncryption
4a:2c:3b:7d:...
A Certificate Authority is a trusted organization that issues and signs SSL certificates. When a CA signs your certificate, browsers trust it automatically.
| Type | Validation Level | Verification Required | Best For |
|---|---|---|---|
| DV (Domain Validated) | Basic | Prove domain ownership (DNS/HTTP challenge) | Personal sites, blogs, dev projects |
| OV (Organization Validated) | Medium | Verify organization identity + domain | Small businesses, internal apps |
| EV (Extended Validation) | Highest | Thorough legal/physical verification | Banks, e-commerce, high-trust sites |
| Wildcard | DV or OV | Same as DV/OV | *.yourdomain.com (all subdomains) |
While HTTP is fine for most local development, you need HTTPS for:
mkcert is a tool that creates locally-trusted development certificates with no configuration.
# Install mkcert # macOS brew install mkcert brew install nss # for Firefox # Linux sudo apt install libnss3-tools wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64 chmod +x mkcert-v1.4.4-linux-amd64 sudo mv mkcert-v1.4.4-linux-amd64 /usr/local/bin/mkcert # Windows (using Chocolatey) choco install mkcert # Step 1: Install local CA mkcert -install # Creates root certificate in system trust store # Step 2: Generate certificate for localhost mkcert localhost 127.0.0.1 ::1 # Creates: localhost+2.pem (certificate) and localhost+2-key.pem (private key) # Step 3: Use in your server # See framework-specific examples below
// Node.js / Express
const fs = require('fs');
const https = require('https');
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello HTTPS!');
});
const options = {
key: fs.readFileSync('./localhost+2-key.pem'),
cert: fs.readFileSync('./localhost+2.pem')
};
https.createServer(options, app).listen(3000, () => {
console.log('HTTPS server running on https://localhost:3000');
});
# React / Create React App # Set environment variables HTTPS=true \ SSL_CRT_FILE=./localhost+2.pem \ SSL_KEY_FILE=./localhost+2-key.pem \ npm start # Or create .env.local file: echo "HTTPS=true" >> .env.local echo "SSL_CRT_FILE=./localhost+2.pem" >> .env.local echo "SSL_KEY_FILE=./localhost+2-key.pem" >> .env.local npm start
// Vite - vite.config.js
import { defineConfig } from 'vite';
import fs from 'fs';
export default defineConfig({
server: {
https: {
key: fs.readFileSync('./localhost+2-key.pem'),
cert: fs.readFileSync('./localhost+2.pem'),
},
port: 3000
}
});
// Next.js - create custom server (server.js)
const { createServer } = require('https');
const { parse } = require('url');
const next = require('next');
const fs = require('fs');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const httpsOptions = {
key: fs.readFileSync('./localhost+2-key.pem'),
cert: fs.readFileSync('./localhost+2.pem'),
};
app.prepare().then(() => {
createServer(httpsOptions, (req, res) => {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
}).listen(3000, (err) => {
if (err) throw err;
console.log('> Ready on https://localhost:3000');
});
});
# Generate self-signed certificate openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout localhost.key \ -out localhost.crt \ -subj "/CN=localhost" # Will create warnings in browser unless manually trusted
Mixed content occurs when an HTTPS page loads resources (images, scripts, stylesheets) over HTTP. This creates a security hole in your HTTPS protection.
<img src="http://example.com/image.jpg"><video src="http://..."><audio src="http://...">Risk: Attacker can replace image with malicious content, but can't execute scripts.
<script src="http://..."><link href="http://..."><iframe src="http://...">fetch('http://...')new Worker('http://...')Risk: Attacker can inject malicious code, steal data, hijack session. Browsers block these by default.
<!-- ❌ Bad: Hard-coded HTTP --> <script src="http://cdn.example.com/app.js"></script> <!-- ✅ Good: Use HTTPS --> <script src="https://cdn.example.com/app.js"></script> <!-- ✅ Good: Protocol-relative URL (inherits page protocol) --> <script src="//cdn.example.com/app.js"></script> <!-- ✅ Good: Relative URL --> <script src="/js/app.js"></script>
Content-Security-Policy: upgrade-insecure-requests
# ngrok - creates HTTPS tunnel to localhost:3000 ngrok http 3000 # Gives you: https://abc123.ngrok.io → localhost:3000
A: Yes! This is standard practice. Server redirects http://example.com → https://example.com with a 301 permanent redirect. Even better: use HSTS (HTTP Strict Transport Security) header to tell browsers to always use HTTPS.
Strict-Transport-Security: max-age=31536000; includeSubDomains
A: SSL (Secure Sockets Layer) is the old name. TLS (Transport Layer Security) is the modern version. SSL 3.0 was deprecated in 2015. We now use TLS 1.2 and TLS 1.3, but people still say "SSL certificate" out of habit. Technically, it should be "TLS certificate".
A: Negligible impact. The TLS handshake adds ~100ms on initial connection. However, HTTP/2 (which requires HTTPS) is often FASTER overall due to multiplexing and header compression. Modern servers handle HTTPS efficiently.
A: No. HTTPS requires an SSL/TLS certificate by definition. But getting one is free and easy with Let's Encrypt or mkcert (for localhost).
A: Browsers will show "Your connection is not private" error and block access. Users CAN bypass it, but it erodes trust. Let's Encrypt certificates expire after 90 days - use automation (certbot) to auto-renew.