Skip to content

SecurityRonin/tls-handshake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

84 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TLS Handshake Visualised — See How HTTPS Works

Netlify Status

Interactive step-by-step TLS 1.3 handshake demonstration plus TLS 1.2 downgrade and legacy attack scenarios. See how key exchange, authentication, encryption, and integrity work together, and trace how different failures or protocol regressions break the channel.

Live Demo →

What It Teaches

Every HTTPS connection starts with a handshake. This demo walks through the TLS 1.3 protocol step by step, mapping each step to the four cryptographic pillars:

  1. ClientHello — Key Exchange begins (ECDHE key share sent)
  2. ServerHello — Key exchange complete; handshake traffic keys derived. Authentication not yet established.
  3. Certificate — Server authenticates: encrypted Certificate + CertificateVerify flight verified. Encryption already active.
  4. Client Finished — Integrity established: Finished authenticates the handshake transcript; both sides derive complementary client/server application traffic secrets via HKDF
  5. Encrypted Data — AEAD-authenticated application records flow (auth tag is integral to the cipher, not a separate HMAC)
  6. Done — All four pillars active. Connection secure.

What-If Scenarios

Toggle scenarios to see how the handshake changes or breaks:

TLS 1.3 — Baseline & Variations

Scenario Effect
HelloRetryRequest Step 2 — server rejects the client's key_share group; client retries with secp256r1, adding one RTT
PSK Session Resumption Step 2 — server accepts a session ticket; ECDHE still used for forward secrecy
0-RTT Early Data Step 5 — early data sent before server Finished; replayable, bound to resumption key (not fresh ECDHE share)
Mutual TLS Step 4 — client presents its own certificate after server CertificateRequest

TLS 1.3 — Certificate & Auth Failures

Scenario Effect
Expired Certificate Step 3 fails — certificate validity period has ended
Hostname Mismatch Step 3 fails — certificate CN/SAN does not match the requested hostname
Weak Signature (SHA-1) Step 3 fails — SHA-1 is cryptographically broken; TLS 1.3 forbids it in CertificateVerify
Revoked Certificate (OCSP staple) Step 3 fails — OCSP staple embedded in Certificate message shows certStatus: revoked
Certificate Pinning Failure Step 3 fails — cert is valid but SPKI hash doesn't match the pinned value
MITM Attempt Step 3 fails — rogue certificate signed by an untrusted CA, or CertificateVerify invalid
Client Authentication Failure Step 4 fails — server required a client certificate; client sent an empty Certificate message

TLS 1.3 — Privacy & Extensions

Scenario Effect
SNI Exposed (no ECH) Step 1 — server name visible in plaintext ClientHello extension
ECH Success Step 1 — inner ClientHello encrypted with server's published public key; supersedes ESNI
ALPN Mismatch Step 3 fails — client offered only h2; server supports only http/1.1; fatal no_application_protocol alert (RFC 7301 §3.3.2)
HSTS Step 6 — server delivers Strict-Transport-Security in the HTTP response; browser enforces HTTPS-only for future visits
QUIC / HTTP/3 contrast Step 1 — educational comparison; QUIC carries the TLS 1.3 handshake inside CRYPTO frames over UDP instead of a TLS record layer

TLS 1.3 — Active Attacks

Scenario Effect
Session Ticket Theft Step 2 — attacker replays a stolen PSK ticket to hijack the session
Record Tampering Step 5 — attacker modifies an application data record; AES-256-GCM detects it via authentication tag mismatch; connection aborted

TLS 1.2 Downgrade path

Scenario Effect
TLS 1.2 downgrade (RSA) Full downgrade — RSA key exchange, no forward secrecy
TLS 1.2 + CBC cipher Warning from step 3 — Lucky13/POODLE exploit CBC padding oracles; BEAST exploits predictable TLS 1.0 CBC IVs
TLS 1.2 + expired certificate Step 2 fails — certificate validity check
Export RSA Downgrade (FREAK) Step 2 — illustrative TLS 1.2 server silently accepts an export-grade RSA suite; downgrade succeeds with no client alert
Export DHE Downgrade (Logjam) Step 2 — illustrative TLS 1.2 server sends weak 512-bit DHE parameters in ServerKeyExchange; shared secret becomes recoverable
Renegotiation Injection Step 5 — pre-RFC 5746 TLS 1.2 allows attacker prefix injection via unauthenticated renegotiation

Development

npm install
npx playwright install chromium
npm run captures:build
python3 -m http.server 3009 --directory web
# Open http://localhost:3009

Capture Fixtures

The repo now includes real local capture fixtures for reproducible TLS 1.3 scenarios in:

  • fixtures/captures/sni.pcap
  • fixtures/captures/hostname.pcap
  • fixtures/captures/mitm.pcap
  • fixtures/captures/client-auth-fail.pcap
  • fixtures/captures/mtls.pcap
  • fixtures/captures/hrr.pcap
  • fixtures/captures/psk-resumption.pcap
  • fixtures/captures/zero-rtt.pcap
  • fixtures/captures/alpn-mismatch.pcap

The repo also keeps illustrative or synthetic fixtures for scenarios that are not straightforward to reproduce honestly on the wire with local tooling:

  • fixtures/captures/freak.pcapng
  • fixtures/captures/logjam.pcapng
  • fixtures/captures/ocsp-revoked.pcapng
  • fixtures/captures/quic-http3.pcapng

Most are generated from source hexdumps in fixtures/capture-src/ using:

npm run captures:build

The real local TLS 1.3 captures are generated with:

npm run captures:real

This command uses openssl s_server, openssl s_client, and tcpdump on lo0, so it requires local packet-capture privileges. These fixtures intentionally preserve loopback addresses (127.0.0.1) because they are genuine captures, not rewritten demos. The manifest at fixtures/captures/manifest.json is refreshed with tshark so both real and illustrative capture assets can be inspected reproducibly rather than edited ad hoc inside the UI.

Testing

npm test

174 Playwright E2E tests covering security headers, happy path, scenario toggles, protocol trees, capture fixtures, and reset.

Tech Stack

  • Vanilla HTML/CSS/JS (single file, no framework)
  • Playwright for E2E testing
  • Netlify for static deployment

Part of The Codebreakers

This demo accompanies The Codebreakers Part II: The Algorithms — an introductory information security course by Albert Hui (Security Ronin).

Licence

MIT

About

Interactive TLS 1.3 handshake visualisation — step through ClientHello to encrypted data, toggle failure scenarios (expired cert, MITM, no forward secrecy, CBC).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors