The TLS 1.3 Handshake, Walked Through
Introduction¶
TLS 1.3 (RFC 8446, 2018) is now the default for most traffic. It's faster — one round trip instead of two — and drops every cipher and feature that caused a decade of vulnerabilities. Knowing the flow helps when a handshake fails or a scanner flags your config.
Concepts¶
TLS does three jobs: authentication (you're really talking to
example.com), key exchange (agree on a shared secret nobody watching can
derive), and encryption (protect the data). TLS 1.3 does key exchange with
ephemeral Diffie-Hellman only, so every session has forward secrecy — capturing
today's traffic and stealing the server key next year still doesn't decrypt it.
The flow¶
Client Server
ClientHello
+ supported_versions: [TLS 1.3]
+ key_share: client's DH public key (guessed group)
+ signature_algorithms, cipher_suites, SNI
-------------------------------------------------->
ServerHello
+ key_share: server's DH public key
+ selected cipher suite
{EncryptedExtensions}
{Certificate} <- now encrypted
{CertificateVerify} <- signs the handshake
{Finished}
<--------------------------------------------------
{Finished}
-------------------------------------------------->
[Application Data flows both ways]
Braces {} mean "encrypted with the handshake key" — in 1.3 the certificate
itself is encrypted, so a passive observer can't see which site you're visiting
from the cert (SNI is still cleartext unless Encrypted Client Hello is used).
Key points:
- The client guesses a DH group and sends its key share in the first
message. If the server likes the guess, that's it — one round trip. If not,
the server sends
HelloRetryRequestasking for a different group (extra round trip, uncommon). CertificateVerifyis the server signing a transcript of everything so far with its private key — that's the actual proof of identity.- Both sides send
Finished(a MAC over the transcript) to confirm nothing was tampered with.
What 1.3 removed from 1.2¶
- RSA key exchange (no forward secrecy), static DH.
- CBC-mode ciphers, RC4, 3DES, SHA-1.
- Renegotiation, compression (CRIME), custom DH groups (Logjam).
- The separate
ChangeCipherSpecstep (kept only as a dummy for middlebox compatibility).
0-RTT resumption¶
On a repeat visit the client can send application data in the very first
packet, encrypted with a key from the previous session (a PSK). It's fast but
replayable — a network attacker can resend that data. Use it only for
idempotent requests (GET), never for anything that changes state.
Hands-on¶
# Force 1.3 and show the negotiated parameters
openssl s_client -connect example.com:443 -servername example.com -tls1_3 </dev/null 2>/dev/null \
| grep -E "Protocol|Cipher|Server Temp Key"
# Full handshake trace
openssl s_client -connect example.com:443 -servername example.com -trace </dev/null
# Which versions/ciphers does the server actually support?
nmap --script ssl-enum-ciphers -p 443 example.com
Server Temp Key: X25519, 253 bits confirms ephemeral ECDH (forward secrecy).
Verification and troubleshooting¶
handshake failure/no protocols available— the client offers only TLS 1.3 and the server maxes out at 1.2 (or vice versa for an old client). Check both ends' min/max version.certificate verify failed: unable to get local issuer certificate— the server isn't sending the intermediate. Servefullchain.pem, not just the leaf. Verify with the SSL/TLS checker or Certificate Decoder.- Handshake works in a browser, fails from
curl/an app — SNI. The client isn't sending the servername, so the server returns the default vhost's cert.curldoes this right; some libraries need it set explicitly. HelloRetryRequestevery time (slow) — the server's preferred group isn't in the client's firstkey_share. Usually harmless; if it's a hot path, align the client's default group with the server's.- Scanner says "weak / deprecated" — you still allow TLS 1.0/1.1 or CBC
ciphers. Set
ssl_protocols TLSv1.2 TLSv1.3;and a modern cipher list. - 0-RTT causing duplicate side effects — disable
early_datafor non-idempotent endpoints.
Related tools and reading¶
- On-site: SSL/TLS Checker, Certificate Decoder, HSTS Preload Checker, CSR Generator.
- Related posts: The TCP three-way handshake, An Nginx reverse proxy with TLS.
Stuck on something this site can't fix?Reach out to Prabath directly on LinkedIn.More in Network Protocols
DHCP DORA: How a Host Gets Its Address
The four DHCP packets, the renewal timers, why relays exist, and the tcpdump filter to watch it happen.
October 24, 2026SMB Versions and Signing, Demystified
SMB1 is a security liability, SMB3 encrypts and signs. Here's how dialect negotiation works and how to tell which one a connection actually used.
October 24, 2026DNS over TLS and DNS over HTTPS
Plain DNS is unencrypted and unauthenticated. DoT and DoH fix the transport — here's how each works, and the trade-off between privacy and network visibility.
October 24, 2026