diagram.mmd — sequence
TLS Handshake sequence diagram

The TLS (Transport Layer Security) handshake is the cryptographic negotiation protocol that establishes a secure, authenticated, and encrypted channel between two parties before any application data is exchanged.

TLS 1.3 (RFC 8446, 2018) significantly simplified and accelerated the handshake compared to TLS 1.2, reducing it from 2 RTTs to 1 RTT for new connections and enabling 0-RTT resumption for returning clients (with replay-attack caveats).

ClientHello: The client initiates the handshake by advertising its supported TLS version (1.3), a list of cipher suites (e.g., TLS_AES_256_GCM_SHA384), and a key share for the expected key agreement algorithm (typically X25519). A random nonce (client_random) is included for key derivation.

ServerHello + Certificate: The server selects the highest mutually supported TLS version and a cipher suite. In TLS 1.3, the server also sends its key share in the same flight, allowing both sides to immediately derive the handshake traffic keys. The server sends its X.509 certificate chain, a CertificateVerify message (a signature proving it holds the certificate's private key), and a Finished MAC.

Client Validation + Finished: The client verifies the certificate chain against trusted root CAs (see TLS Certificate Validation), checks the CertificateVerify signature, and sends its own Finished message. Both sides now derive identical application traffic keys from the shared secret.

Application Data: All subsequent data is encrypted with symmetric keys (AES-GCM or ChaCha20-Poly1305). The asymmetric operations in the handshake are computationally expensive but happen only once per connection.

TLS is layered under both HTTPS and, in modified form, QUIC — the transport behind HTTP/3. The TCP Three-Way Handshake must complete before TLS can begin for TCP-based connections.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

The TLS handshake is the cryptographic negotiation that establishes a secure, authenticated, and encrypted channel between client and server. It authenticates the server (via X.509 certificate), agrees on cipher suites, performs key exchange, and derives symmetric session keys — all before any application data is transmitted.
The client sends a `ClientHello` advertising supported cipher suites and a key share for the expected algorithm. The server responds with `ServerHello` (selecting cipher and sending its own key share), followed by its certificate, a `CertificateVerify` signature, and a `Finished` MAC — all in one flight. Both sides can immediately derive session keys from the exchanged key shares. The client validates the certificate and sends its `Finished`. The full exchange takes 1 RTT.
TLS 1.3 reduces handshake latency from 2 RTTs (TLS 1.2) to 1 RTT. It removes weak cipher suites, mandatory forward secrecy is enforced (only ECDHE key exchange), and the server's certificate is encrypted in transit. TLS 1.3 also introduces 0-RTT session resumption. TLS 1.2 is still widely supported but is being deprecated in favour of 1.3.
0-RTT allows a returning client to send application data in the first TLS record using a pre-shared session ticket from a previous connection. This eliminates handshake latency entirely for repeat visitors. However, 0-RTT data can be replayed by an attacker who captures the initial flight. It is only safe to use for idempotent requests (GET, HEAD) where replaying the request has no adverse effect.
The client aborts the TLS handshake and the connection is refused. Common reasons include: the certificate has expired, the hostname does not match any Subject Alternative Name on the certificate, the certificate was issued by an untrusted CA (or is self-signed), or the system clock is wrong, causing the certificate to appear not yet valid or already expired.
mermaid
sequenceDiagram participant Client participant Server note">Note over Client,Server: TLS 1.3 Handshake (1 RTT) Client->>Server: ClientHello\n(TLS 1.3, cipher suites, key_share, client_random) Server-->>Client: ServerHello\n(selected cipher, key_share, server_random) note">Note over Client,Server: Both derive Handshake Traffic Keys Server-->>Client: EncryptedExtensions Server-->>Client: Certificate (X.509 chain) Server-->>Client: CertificateVerify (signature with private key) Server-->>Client: Finished (HMAC over handshake) note">Note over Client: Verify certificate chain\nVerify CertificateVerify signature\nVerify Finished MAC Client->>Server: Finished (HMAC over handshake) [encrypted] note">Note over Client,Server: Both derive Application Traffic Keys Client->>Server: Application Data [encrypted with AES-GCM] Server-->>Client: Application Data [encrypted with AES-GCM] note">Note over Client,Server: Session ticket for 0-RTT resumption Server-->>Client: NewSessionTicket
Copied to clipboard