6.1 Tại sao cần HTTPS?
HTTP plain có 3 vấn đề bảo mật:
- Sniffing (eavesdropping): bất kỳ ai trên đường truyền (Wi-Fi cùng quán cà phê, ISP) đều đọc được password, cookie
- Tampering: attacker chèn quảng cáo, JavaScript độc vào response (xảy ra với ISP một số nước)
- Impersonation: attacker giả mạo server (DNS spoofing, ARP poisoning)
HTTPS = HTTP + TLS (Transport Layer Security). Giải quyết cả 3:
- Confidentiality: mã hoá → không sniff được
- Integrity: MAC (Message Authentication Code) → phát hiện tamper
- Authentication: certificate → xác thực server thật là server
HTTPS port
Mặc định 443. HTTP plain: 80.
6.2 Symmetric vs Asymmetric Encryption
Symmetric — 1 key cho cả encrypt và decrypt
- Vd: AES, ChaCha20
- Cực nhanh — hardware AES-NI có thể đạt nhiều GB/s
- Vấn đề: làm sao 2 bên có cùng key mà không bị lộ qua network?
Asymmetric — 2 key (public + private)
- Vd: RSA, ECDSA, EdDSA
- Encrypt bằng public key → chỉ private key decrypt được
- Sign bằng private key → bất kỳ ai có public key cũng verify được
- Chậm hơn symmetric ~1000x
- Giải quyết được vấn đề key exchange
TLS dùng cả hai
- Asymmetric chỉ dùng 1 lần ở handshake để trao đổi 1 "session key" symmetric
- Sau đó dùng symmetric để mã hoá data thực — nhanh
Đây là hybrid encryption — kết hợp ưu điểm cả hai.
6.3 TLS 1.2 Handshake — phải vẽ được
Đây là phần phỏng vấn hay yêu cầu vẽ. TLS 1.2 cần ~2 RTT.
Các bước key
- Client Hello: client báo TLS version + danh sách cipher mình support + client random
- Server Hello: server chọn cipher + gửi server random + certificate
- Verify cert: client check cert chain, hostname, expiry
- Key Exchange: client tạo pre-master secret, encrypt bằng server's public key, gửi
- Derive session key: 2 bên dùng pre-master + 2 random → derive cùng 1 session key (symmetric)
- Finished: 2 bên gửi message encrypted để confirm
2 RTT trước khi có thể gửi HTTP request. Cộng với 1.5 RTT của TCP = 3.5 RTT tổng cho HTTPS qua HTTP/1.1.
6.4 TLS 1.3 (2018) — đơn giản hoá đáng kể
TLS 1.3 cải tiến lớn:
1. Handshake còn 1 RTT
Client gửi key share luôn ở Client Hello — không đợi 1 round nữa.
2. 0-RTT với session resumption
Nếu client đã connect server trước đây, có "PSK" (pre-shared key) → có thể gửi data ngay trong Client Hello đầu tiên. 0 RTT!
Trade-off: 0-RTT data có thể bị replay attack — chỉ dùng cho idempotent request.
3. Forward secrecy bắt buộc
Bỏ các cipher không có Perfect Forward Secrecy. Nếu private key server bị lộ trong tương lai, traffic cũ vẫn an toàn.
4. Bỏ các thứ cũ kỹ
- Bỏ RSA key exchange (chỉ dùng (EC)DHE)
- Bỏ MD5, SHA-1, RC4, 3DES
- Bỏ static DH
- Bỏ compression (CRIME attack)
6.5 Certificate & PKI — làm sao biết server là thật?
Vấn đề: client nhận được public key — làm sao biết key đó là của google.com thật, không phải của attacker?
Giải pháp: Public Key Infrastructure (PKI). Browser tin tưởng một danh sách Root CA (Certificate Authority). Mỗi cert phải được sign bởi một CA trong chain dẫn về Root.
Certificate chain
Verify cert
Client kiểm tra theo thứ tự:
- Signature chain: leaf signed by intermediate, intermediate signed by root, root in trusted store
- Domain matches: cert có Subject Alternative Name (SAN) khớp domain đang truy cập
- Validity period: chưa expired, chưa "not yet valid"
- Revocation: chưa bị revoke (qua CRL hoặc OCSP)
Một bước fail → browser hiển thị warning đỏ.
Self-signed certificate
Bạn có thể tự tạo cert mà không qua CA. Browser sẽ warning vì không trust. Dùng cho dev/test, không cho production public.
6.6 Let's Encrypt — TLS miễn phí cho mọi người
Trước 2015, mua cert từ DigiCert/Comodo tốn $50-500/năm. Let's Encrypt (2015) cấp free, automated qua giao thức ACME.
Domain Validation (DV) flow
- Server gọi Let's Encrypt: "Tôi muốn cert cho example.com"
- LE: "Đặt file
/.well-known/acme-challenge/<token>trên http://example.com với content X" - Server đặt file
- LE truy cập
http://example.com/.well-known/acme-challenge/<token>→ đọc được X → chứng minh server kiểm soát domain - LE cấp cert valid 90 ngày
Tools: certbot, caddy (auto), traefik (auto).
# Certbot
sudo certbot --nginx -d example.com -d www.example.com
# Hoặc Caddy auto:
# Caddyfile:
example.com {
reverse_proxy localhost:3000
}
# Chạy caddy → tự xin cert + renew
Cert validity 90 ngày — vì sao ngắn?
- Buộc auto-renew → nếu compromise, "blast radius" nhỏ
- Khuyến khích automation — không ai nên renew tay mỗi năm
6.7 SNI — Server Name Indication
Vấn đề: 1 web server có IP duy nhất nhưng host nhiều domain (vd siteA.com, siteB.com). Khi TLS handshake bắt đầu, server chưa biết domain nào — chưa thể chọn đúng cert.
Giải pháp: SNI = client gửi domain trong Client Hello (plaintext). Server đọc, chọn đúng cert.
SNI là plaintext → ISP/firewall biết bạn đang truy cập domain nào (mặc dù không thấy URL/data nhờ HTTPS).
Giải pháp: Encrypted Client Hello (ECH) — encrypt SNI bằng key của front server. Đang được Cloudflare push nhưng chưa universal.
6.8 Cipher Suite & Perfect Forward Secrecy
Cipher suite
Một cipher suite chỉ định 4 thuật toán:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
│ │ │ │ │
│ │ │ │ └─ MAC: SHA-256
│ │ │ └────────────── Cipher: AES-128-GCM
│ │ └────────────────────── Auth: RSA cert
│ └──────────────────────────── Key Exchange: ECDHE (Elliptic Curve DH Ephemeral)
└────────────────────────────────── Protocol: TLS
TLS 1.3 đơn giản hoá: chỉ chỉ định AEAD + hash, key exchange tách biệt:
TLS_AES_128_GCM_SHA256
│ │ │
│ │ └─ MAC/KDF: SHA-256
│ └─────────────── AEAD: AES-128-GCM
└─────────────────────── Protocol
Perfect Forward Secrecy (PFS)
Vấn đề: nếu attacker ghi lại traffic encrypted hôm nay, năm sau bằng cách nào đó có private key của server, có thể decrypt traffic cũ.
Giải pháp PFS: mỗi session dùng ephemeral key — sau session, key bị huỷ. Server private key chỉ dùng để authenticate, không trực tiếp encrypt data.
(EC)DHE = (Elliptic Curve) Diffie-Hellman Ephemeral cho PFS. Static RSA không có PFS → TLS 1.3 bỏ.
6.9 Tools thực tế
openssl — Swiss Army knife
# Inspect cert của 1 server
openssl s_client -connect example.com:443 -servername example.com
# Show full handshake + cert chain
# Chỉ lấy cert
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text
# Check expiry
echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -dates
# Test specific TLS version
openssl s_client -tls1_3 -connect example.com:443
curl
curl -v https://example.com 2>&1 | grep -E '(TLS|cert|CN)'
# * TLSv1.3 (OUT), TLS handshake, Client hello (1)
# * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
# * Server certificate:
# * subject: CN=example.com
# * issuer: ...
SSL Labs — test online
https://www.ssllabs.com/ssltest/ — chấm điểm A+ đến F cho cấu hình TLS server. Kiểm tra: weak ciphers, cert chain, HSTS, ...
Chrome DevTools
Browser → Padlock icon → Connection is secure → Certificate viewer. Show full chain, validity, fingerprints.
Bài tập
Chạy openssl s_client -connect github.com:443. Tìm: TLS version, cipher, cert chain, expiry.
Tạo self-signed cho localhost: openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 30 -subj "/CN=localhost". Dùng cho local HTTPS test.
Trên giấy, vẽ đầy đủ TLS 1.2 handshake — labels mỗi message, ai gửi cho ai. Đếm số RTT.
Thuê 1 VPS (DigitalOcean $5), trỏ subdomain về VPS. Cài Caddy, viết Caddyfile. Quan sát Caddy tự xin cert.
Test 3 site quen thuộc trên ssllabs.com (vd github.com, facebook.com, site cá nhân). So sánh điểm.
Khi vào https://example.com, attacker trên cùng Wi-Fi có thể biết: (a) URL? (b) Domain? (c) Cookie? (d) Password gửi POST? (e) Kích thước response? Trả lời từng câu.
🧪 Quiz cuối chương
Câu 1. HTTPS đảm bảo 3 tính chất?
Đáp án: Confidentiality + Integrity + Authentication. 3 vấn đề HTTP plain không giải quyết được.
Câu 2. TLS dùng cả symmetric và asymmetric vì?
Đáp án: hybrid encryption. Asymmetric chỉ ở handshake; sau đó symmetric với session key.
Câu 3. TLS 1.3 cần bao nhiêu RTT cho handshake?
Đáp án: 1 RTT. Cải thiện đáng kể từ 2 RTT của TLS 1.2. Có thể 0-RTT với PSK resumption.
Câu 4. Browser verify certificate bằng cách?
Đáp án: chain → root CA + hostname + expiry + revocation. Bất kỳ bước fail → warning đỏ.
Câu 5. Perfect Forward Secrecy (PFS) là?
Đáp án: ephemeral session key. (EC)DHE cho PFS. Static RSA không có → TLS 1.3 bỏ.
Câu 6. Let's Encrypt cấp cert miễn phí bằng cách?
Đáp án: HTTP-01 challenge. Server đặt file đặc biệt → LE truy cập → confirm ownership → cấp cert.
Câu 7. SNI dùng để?
Đáp án: 1 IP host nhiều domain. Plaintext → privacy issue, ECH đang giải quyết.
Câu 8. Khi attacker trên cùng Wi-Fi với bạn truy cập https://bank.com, attacker biết được gì?
Đáp án: domain + IP + size. HTTPS bảo vệ content nhưng metadata vẫn lộ. ECH + DoH/DoT để giấu domain.
Tổng kết chương 6
- ✅ HTTPS = HTTP + TLS, cho 3 tính chất: Confidentiality + Integrity + Authentication
- ✅ Hybrid encryption: Asymmetric ở handshake → Symmetric cho data
- ✅ TLS 1.2 handshake: 2 RTT; TLS 1.3: 1 RTT (hoặc 0-RTT với PSK)
- ✅ Certificate chain: leaf → intermediate → root CA. Browser tin sẵn root CA
- ✅ Browser verify: chain + hostname + expiry + revocation
- ✅ Let's Encrypt: free, automated qua ACME, HTTP-01 challenge, valid 90 ngày
- ✅ SNI: 1 IP nhiều domain; SNI plaintext → ECH bắt đầu phổ biến
- ✅ PFS: ephemeral key mỗi session, lộ private key tương lai cũng an toàn traffic cũ
- ✅ Tools:
openssl s_client,curl -v, SSL Labs, Chrome DevTools - ✅ HTTPS bảo vệ content nhưng không hide: domain (SNI/DNS), IP, kích thước