Protokol

TLS 1.3 Deep Dive

Panduan mendalam TLS 1.3 (RFC 8446) — handshake 1-RTT dan 0-RTT resumption, cipher suites yang disederhanakan, Perfect Forward Secrecy mandatory, Certificate Transparency, dan perbandingan dengan TLS 1.2

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

AspekTLS 1.2TLS 1.3
Handshake RTT2-RTT1-RTT (0-RTT untuk resumption)
Cipher SuitesBanyak (300+ kombinasi)Hanya 5 (sederhana, aman)
Key ExchangeRSA, DHE, ECDHEHanya (EC)DHE — PFS mandatory
RSA Key ExchangeDidukung (tanpa PFS)Dihapus total
Static DHDidukungDihapus (hanya ephemeral)
CompressionDidukung (rentan CRIME)Dihapus
RenegotiationDidukung (kompleks, rentan)Dihapus
Handshake EncryptionTidak (plaintext)Ya — setelah key exchange, semua terenkripsi
Encrypted SNITidakDiarahkan (dengan ECH)
ModeTLS + DTLSTLS 1.3 + DTLS 1.3
💡 Mengapa TLS 1.3 Lebih Aman?

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.

Text
# === 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

Text
# 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.

Text
# === 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 SuiteAEAD AlgorithmHashKey Size
TLS_AES_128_GCM_SHA256AES-128-GCMSHA-256128 bit
TLS_AES_256_GCM_SHA384AES-256-GCMSHA-384256 bit
TLS_CHACHA20_POLY1305_SHA256ChaCha20-Poly1305SHA-256256 bit
TLS_AES_128_CCM_SHA256AES-128-CCMSHA-256128 bit
TLS_AES_128_CCM_8_SHA256AES-128-CCM-8SHA-256128 bit
📚 Mengapa Hanya AEAD?

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

Text
# 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.

Text
# 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

FiturTLS 1.2TLS 1.3
Full Handshake2-RTT1-RTT
Resumption1-RTT (session ticket)0-RTT
Cipher Suites300+5
PFSOpsionalWajib
Handshake EncryptionTidakYa
RSA Key ExchangeYaTidak (hapus)
CompressionYaTidak (hapus)
RenegotiationYaTidak (hapus)
CCS MessageYaTidak (hapus)
Signature SchemesDi cipher suiteIndependent extension
Browser SupportSemua modernSemua modern (sejak 2020)
Adoption Rate (2026)~35%~65%

8. Konfigurasi & Testing

Nginx TLS 1.3 Configuration

Nginx
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

Bash
# 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

Text
# 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)

Text
# 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

Quiz Pemahaman

Pertanyaan 1: Berapa RTT yang dibutuhkan TLS 1.3 untuk full handshake baru?

a) 3 RTT
b) 2 RTT
c) 1 RTT
d) 0 RTT

Pertanyaan 2: Mengapa TLS 1.3 menghapus RSA key exchange?

a) Terlalu lambat
b) Tidak mendukung Perfect Forward Secrecy
c) Tidak kompatibel dengan HTTP/2
d) Terlalu rumit untuk diimplementasikan

Pertanyaan 3: Risiko utama dari 0-RTT di TLS 1.3?

a) Latency lebih tinggi
b) Replay attack
c) Kompatibilitas browser
d) Ukuran sertifikat lebih besar

Pertanyaan 4: Berapa banyak cipher suites yang didukung TLS 1.3?

a) 300+
b) 50
c) 20
d) 5

Pertanyaan 5: Apa fungsi Certificate Transparency?

a) Mengenkripsi sertifikat
b) Memantau dan mengaudit penerbitan sertifikat SSL/TLS
c) Mempercepat TLS handshake
d) Menggantikan CA
🔍 Zoom
100%
🎨 Tema