1. Apa yang Baru di TLS 1.3?
TLS 1.3 (RFC 8446, Agustus 2018) adalah revisi besar dari protokol keamanan transport yang paling banyak digunakan di internet. TLS 1.3 bukan sekadar upgrade — ini adalah redesign fundamental yang menghilangkan banyak fitur legacy yang lemah dan menambah fitur keamanan modern.
Perubahan Utama dari TLS 1.2
| Aspek | TLS 1.2 | TLS 1.3 |
|---|---|---|
| Handshake RTT | 2-RTT | 1-RTT (0-RTT untuk resumption) |
| Cipher Suites | Banyak (300+ kombinasi) | Hanya 5 (sederhana, aman) |
| Key Exchange | RSA, DHE, ECDHE | Hanya (EC)DHE — PFS mandatory |
| RSA Key Exchange | Didukung (tanpa PFS) | Dihapus total |
| Static DH | Didukung | Dihapus (hanya ephemeral) |
| Compression | Didukung (rentan CRIME) | Dihapus |
| Renegotiation | Didukung (kompleks, rentan) | Dihapus |
| Handshake Encryption | Tidak (plaintext) | Ya — setelah key exchange, semua terenkripsi |
| Encrypted SNI | Tidak | Diarahkan (dengan ECH) |
| Mode | TLS + DTLS | TLS 1.3 + DTLS 1.3 |
TLS 1.3 menghapus semua algoritma dan fitur yang terbukti lemah: RSA key exchange (tanpa PFS), CBC mode ciphers, RC4, SHA-1 signatures, static DH, compression, dan renegotiation. Hasilnya: lebih sedikit attack surface dan konfigurasi yang lebih aman secara default.
2. 1-RTT Handshake
Di TLS 1.2, handshake memerlukan 2 round-trip sebelum data pertama bisa dikirim. TLS 1.3 mengurangi ini menjadi 1 round-trip — penghematan ~100ms pada koneksi latency tinggi.
# === TLS 1.3 Full Handshake (1-RTT) ===
Client Server
| |
|--- ClientHello --------→ |
| + supported_versions: [TLS 1.3] |
| + key_share: x25519 public key |
| + supported_groups: [x25519, secp256r1] |
| + signature_algorithms: [ecdsa_secp256r1_sha256] |
| + psk_key_exchange_modes: [psk_dhe_ke] |
| + server_name: example.com (SNI) |
| + early_data (jika 0-RTT) |
| |
|←-- ServerHello -------- |
| + supported_version: TLS 1.3 |
| + key_share: x25519 public key |
| + key_exchange: (server public key) |
| |
|←-- {EncryptedExtensions} |
| + server_name (jika matched) |
| + application_layer_protocol: h2 |
| |
|←-- {Certificate} |
| Server certificate (encrypted!) |
| |
|←-- {CertificateVerify} |
| Signature over handshake transcript |
| |
|←-- {Finished} |
| HMAC over full transcript |
| |
|--- {Finished} --------→ |
| HMAC over full transcript |
| |
|==== APPLICATION DATA ========→ |
|←========================== APPLICATION DATA |
# Tanda {curly braces} = encrypted
# Setelah ServerHello, semua pesan terenkripsi!
# TLS 1.2: ClientHello, ServerHello, Certificate semua plaintext
# TLS 1.3: Hanya ClientHello dan ServerHello yang plaintext
Key Derivation
# TLS 1.3 Key Derivation menggunakan HKDF (HMAC-based KDF): # 1. Shared Secret = ECDHE(client_private, server_public) # 2. Early Secret = HKDF-Extract(0, PSK or 0) # 3. Handshake Secret = HKDF-Extract(Derive-Secret(Early Secret, "derived"), ECDHE) # 4. Master Secret = HKDF-Extract(Derive-Secret(Handshake Secret, "derived"), 0) # Key schedule: # # 0 (ikm) # │ # ┌────────▼────────┐ # │ HKDF-Extract │ # │ (salt = 0) │ # └────────┬────────┘ # │ # Early Secret # │ # ┌─────────────┼─────────────┐ # ▼ ▼ ▼ # Client Early Handshake Early Traffic # Traffic Secret Secret Keys # │ # ┌────────┼────────┐ # ▼ ▼ # Client Handshake Server Handshake # Traffic Secret Traffic Secret # │ # Master Secret # │ # ┌─────────────┼─────────────┐ # ▼ ▼ ▼ # Client App Server App Resumption # Traffic Secret Traffic Secret Master Secret
3. 0-RTT Resumption
Fitur paling revolusioner TLS 1.3: 0-RTT (Zero Round Trip Time Resumption). Client yang pernah terhubung sebelumnya bisa mengirim data aplikasi pada message pertama, tanpa menunggu handshake selesai. Ini mengurangi latency ke nol.
# === TLS 1.3 0-RTT Resumption ===
# Prasyarat: Client sudah pernah connect ke server ini
# Client menyimpan PSK (Pre-Shared Key) dari sesi sebelumnya
Client Server
| |
|--- ClientHello --------→ |
| + psk_identity: ticket dari sesi sebelumnya |
| + early_data indicator |
| + key_share |
| |
|--- {0-RTT Application Data} ---→ | ← DATA DIKIRIM SEKARANG!
| (GET /index.html) | TANPA TUNGGU SERVER!
| |
|←-- ServerHello |
| + pre_shared_key: selected identity |
| |
|←-- {EncryptedExtensions} |
|←-- {Finished} |
| |
|--- {Finished} --------→ |
| |
|==== APPLICATION DATA =======→ |
|←========================== APPLICATION DATA |
# KEUNTUNGAN: 0 RTT untuk data pertama
# → 100ms hemat pada koneksi 50ms latency
# → User experience lebih cepat
# ⚠️ RISIKO: Replay Attack!
# 0-RTT data TIDAK memiliki forward secrecy
# Attacker bisa merekam dan me-replay 0-RTT data
# → Server HARUS implementasi anti-replay:
# 1. Single-use tickets (server track ticket yang sudah dipakai)
# 2. Client Hello recording window
# 3. Hanya untuk idempotent requests (GET, bukan POST yang mengubah state)
4. Cipher Suites
TLS 1.3 secara drastis menyederhanakan cipher suites dari ratusan kombinasi menjadi hanya 5:
| Cipher Suite | AEAD Algorithm | Hash | Key Size |
|---|---|---|---|
TLS_AES_128_GCM_SHA256 | AES-128-GCM | SHA-256 | 128 bit |
TLS_AES_256_GCM_SHA384 | AES-256-GCM | SHA-384 | 256 bit |
TLS_CHACHA20_POLY1305_SHA256 | ChaCha20-Poly1305 | SHA-256 | 256 bit |
TLS_AES_128_CCM_SHA256 | AES-128-CCM | SHA-256 | 128 bit |
TLS_AES_128_CCM_8_SHA256 | AES-128-CCM-8 | SHA-256 | 128 bit |
TLS 1.3 hanya mengizinkan AEAD (Authenticated Encryption with Associated Data) cipher modes. Mode lama seperti CBC (Cipher Block Chaining) rentan terhadap padding oracle attacks (POODLE, Lucky13). AEAD menggabungkan enkripsi dan autentikasi dalam satu operasi, menghilangkan kelas serangan ini.
5. Key Exchange & Perfect Forward Secrecy
# Perfect Forward Secrecy (PFS) di TLS 1.3: # TLS 1.2 (opsional PFS): # - RSA key exchange: server punya RSA key pair static # → Client encrypt pre-master secret dengan server public key # → Jika private key bocor NANTI, semua komunikasi masa lalu bisa di-decrypt! # → TIDAK ada PFS # TLS 1.3 (PFS WAJIB): # - Hanya ephemeral (EC)DHE key exchange # → Client dan server generate key pair BARU setiap handshake # → Shared secret = ECDHE(client_ephemeral_private, server_ephemeral_public) # → Setelah handshake selesai, ephemeral keys dihapus # → Jika private key bocor nanti, komunikasi masa lalu TETAP AMAN # → PFS DIJAMIN # Supported Groups di TLS 1.3: # x25519 → Curve25519 (paling populer, cepat, aman) # x448 → Curve448 (keamanan lebih tinggi) # secp256r1 → P-256 (NIST curve, widely supported) # secp384r1 → P-384 (NIST curve, higher security) # secp521r1 → P-521 (NIST curve, highest security) # ffdhe2048 → Finite Field DH 2048-bit # ffdhe3072 → Finite Field DH 3072-bit # Rekomendasi: x25519 (default di sebagian besar library)
6. Certificate Transparency
Certificate Transparency (CT) adalah framework untuk memantau dan mengaudit penerbitan sertifikat SSL/TLS. CT mewajibkan semua sertifikat yang diterbitkan oleh CA (Certificate Authority) dicatat di public append-only logs.
# Certificate Transparency Flow: # 1. CA menerbitkan sertifikat untuk domain # 2. CA meng-submit sertifikat ke CT Log server # 3. CT Log mengembalikan SCT (Signed Certificate Timestamp) # 4. SCT disertakan di sertifikat atau dikirim via TLS extension # SCT (Signed Certificate Timestamp): # - Bukti bahwa sertifikat telah dicatat di public log # - Browser Chrome menolak sertifikat tanpa SCT (sejak 2018) # - Minimal 2-3 SCT dari log berbeda untuk redundansi # Bagaimana CT mendeteksi sertifikat palsu: # # 1. Attacker memperoleh sertifikat palsu dari CA nakal # 2. Sertifikat harus di-submit ke CT log (public!) # 3. Domain owner memonitor CT logs # 4. Domain owner mendeteksi sertifikat yang tidak sah # 5. Domain owner bisa melapor ke browser → sertifikat di-revoke # Monitoring CT logs: # - crt.sh — https://crt.sh (free, searchable) # - Facebook CT Monitor # - Certstream — real-time certificate feed # - Custom monitoring dengan CT log API # Cek sertifikat CT: curl -s "https://crt.sh/?q=example.com&output=json" | python -m json.tool
7. TLS 1.2 vs TLS 1.3
| Fitur | TLS 1.2 | TLS 1.3 |
|---|---|---|
| Full Handshake | 2-RTT | 1-RTT |
| Resumption | 1-RTT (session ticket) | 0-RTT |
| Cipher Suites | 300+ | 5 |
| PFS | Opsional | Wajib |
| Handshake Encryption | Tidak | Ya |
| RSA Key Exchange | Ya | Tidak (hapus) |
| Compression | Ya | Tidak (hapus) |
| Renegotiation | Ya | Tidak (hapus) |
| CCS Message | Ya | Tidak (hapus) |
| Signature Schemes | Di cipher suite | Independent extension |
| Browser Support | Semua modern | Semua modern (sejak 2020) |
| Adoption Rate (2026) | ~35% | ~65% |
8. Konfigurasi & Testing
Nginx TLS 1.3 Configuration
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
# Aktifkan TLS 1.3 (dan TLS 1.2 untuk kompatibilitas)
ssl_protocols TLSv1.2 TLSv1.3;
# TLS 1.3 cipher suites (auto-selected, tapi bisa di-configure)
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
# TLS 1.2 cipher suites (PFS-only)
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers on;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/chain.pem;
# TLS session settings
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Lebih aman tanpa session tickets
# Early data (0-RTT) — HATI-HATI dengan replay
ssl_early_data on;
# Security headers
add_header Strict-Transport-Security "max-age=63072000" always;
}
Testing TLS Configuration
# Cek TLS versi yang didukung openssl s_client -connect example.com:443 -tls1_3 # Output: Protocol : TLSv1.3 # Cek cipher suite yang dinegosiasikan openssl s_client -connect example.com:443 2>/dev/null | grep "Cipher is" # Cipher is TLS_AES_256_GCM_SHA384 # Cek detail handshake openssl s_client -connect example.com:443 -tlsextdebug -status 2>&1 | grep -i "TLS\|extension\|Cipher" # Online testing (sangat lengkap): # https://www.ssllabs.com/ssltest/ # → Grade A+ = TLS 1.3 + HSTS + OCSP stapling + PFS # curl dengan TLS 1.3 verbose curl -v --tlsv1.3 https://example.com 2>&1 | grep -i "TLS\|SSL" # Nmap TLS scanning nmap --script ssl-enum-ciphers -p 443 example.com
TLS 1.3 Adoption di Browser
# TLS 1.3 Support Timeline: # # Chrome 70 (Oktober 2018) — TLS 1.3 final # Firefox 63 (Oktober 2018) — TLS 1.3 final # Safari 12.1 (Maret 2019) — TLS 1.3 final # Edge 79 (Januari 2020) — Chromium-based, TLS 1.3 # Android (API 29+) — TLS 1.3 default # Java 11+ (2018) — TLS 1.3 support # Go 1.13+ (2019) — TLS 1.3 default # OpenSSL 1.1.1 (2018) — TLS 1.3 support # BoringSSL (2018) — TLS 1.3 default # # Server support: # Nginx 1.13.0+ → TLS 1.3 dengan OpenSSL 1.1.1+ # Apache 2.4.37+ → TLS 1.3 # HAProxy 2.0+ → TLS 1.3 # Caddy 2.0 → TLS 1.3 default # Node.js 12+ → TLS 1.3 via OpenSSL # Python 3.7+ → ssl.PROTOCOL_TLS_CLIENT (auto TLS 1.3) # Statistik global (2026): # ~65% koneksi HTTPS menggunakan TLS 1.3 # ~35% masih TLS 1.2 (backward compatibility) # TLS 1.0/1.1: hampir 0% (deprecated sejak 2020)
Encrypted Client Hello (ECH)
# Encrypted Client Hello (ECH) — formerly Encrypted SNI (ESNI) # MASALAH: # Di TLS 1.3, ClientHello (termasuk SNI/Server Name Indication) # dikirim dalam PLAINTEXT sebelum enkripsi diaktifkan. # → Network observer (ISP, firewall) bisa melihat domain # yang Anda kunjungi meski payload terenkripsi! # → Digunakan oleh beberapa negara/ISP untuk censorship/monitoring # SOLUSI: ECH (Encrypted Client Hello) # → Mengenkripsi SELEURUH ClientHello termasuk SNI # → Hanya "outer" SNI yang plaintext (misal: cloudflare.com) # → "Inner" SNI yang sebenarnya terenkripsi # → DNS HTTPS record digunakan untuk publish ECH config # ECH Flow: # 1. Client resolve DNS → dapat ECHConfig (public key server) # 2. Client buat "inner ClientHello" (domain sebenarnya) # 3. Client encrypt inner CH dengan public key server # 4. Client buat "outer ClientHello" (domain generik) # 5. Server decrypt inner CH → proses handshake normal # # Status: Draft standard, didukung Chrome/Firefox (experimental) # Cloudflare sudah mendukung ECH untuk domain yang di-hosting