Skip to content

TLS Handshake Explained

The TLS 1.2 and 1.3 handshake message flow, cipher-suite anatomy, and session resumption, with the failure mode of each step.

TLS 1.3 encrypts nearly the whole handshake; TLS 1.2 exchanges certificates and key material in the clear. These rows follow each message, who sends it, and how the step fails.

Reference table · 31 entries
31 of 31 rows
TLS 1.3 flow
ClientHelloClientCarries key_share, supported_versions, groups, signature algorithms, SNI, and ALPN.No overlap with the server ends in a handshake_failure alert.
HelloRetryRequestServerAsks the client to retry with a key group the server supports.A group mismatch costs one extra round trip.
ServerHelloServerPicks the suite, echoes the version, and returns the server key_share.Downgrade attempts surface as sentinel values caught at Finished.
EncryptedExtensionsServerCarries the remaining server parameters; everything past ServerHello is encrypted.No agreed ALPN protocol ends in a no_application_protocol alert.
CertificateServerSends the certificate chain, already encrypted.An untrusted chain ends in a certificate_unknown alert.
CertificateVerifyServerSigns the whole transcript with the certificate's private key.A bad signature ends in a decrypt_error alert.
FinishedBothHMAC over the transcript proves both sides derived the same keys.A mismatch tears the connection down before any data flows.
NewSessionTicketServerIssued after the handshake for later resumption.A rotation window shorter than the client cache causes misses.
TLS 1.2 flow
ClientHelloClientLists cipher suites, extensions, SNI, and the session ID.No shared suite ends in a handshake_failure alert.
ServerHelloServerPicks the protocol version and the cipher suite.Old middleboxes reject version values they never saw, which is why 1.3 disguises itself as 1.2.
CertificateServerSends the certificate chain in clear text.An expired certificate ends in a certificate_expired alert.
ServerKeyExchangeServerSends signed ECDHE parameters for forward secrecy.Static RSA suites omit it and lose forward secrecy.
CertificateRequestServerAsks the client for a certificate in mutual TLS.A rejected client certificate ends in a handshake_failure alert.
ServerHelloDoneServerEnds the server's first flight.Messages out of flight order end in an unexpected_message alert.
ClientKeyExchangeClientCarries the premaster encrypted to the server key, or the client ECDHE share.A wrong premaster surfaces later as bad_record_mac at Finished.
ChangeCipherSpecBothSignals that every following record uses the negotiated keys.A ChangeCipherSpec at the wrong point ends in an unexpected_message alert.
FinishedBothFirst encrypted record; verifies the transcript with the PRF.A verify_data mismatch ends in a bad_record_mac alert.
Resumption
Session IDClientTLS 1.2 style: the server caches session state and the ClientHello repeats the ID.A server cache miss falls back to a full handshake.
Session ticketBothThe server hands back encrypted state (RFC 5077); the client stores and presents it.Sharing one ticket key across servers breaks isolation between them.
NewSessionTicketServerTLS 1.3 post-handshake tickets carry a PSK identity for the next connection.Replaying a single-use ticket gets it refused.
PSK offerClientThe ClientHello offers the identity plus a binder that proves possession of the key.A binder that fails verification aborts the handshake.
PSK + ECDHEBothpsk_dhe_ke mixes the ticket with a fresh key exchange.Resuming with PSK alone drops forward secrecy.
0-RTT early dataClientApplication data rides the first flight under the ticket keys.Replayable by design; only idempotent requests belong here.
Anti-replayServerSingle-use tickets or a freshness window stop replayed early data.Skipping it turns 0-RTT into a replay oracle.
Cipher suite anatomy
Key exchangeNegotiatedECDHE derives fresh shared keys per session; static RSA reuses the certificate key.Static RSA exchange loses forward secrecy.
AuthenticationNegotiatedRSA, ECDSA, or Ed25519 signs the exchange; TLS 1.3 splits this from key exchange.SHA-1 signatures get rejected by modern clients.
Bulk cipherNegotiatedAES-GCM or ChaCha20-Poly1305 encrypts the record stream.CBC suites carry padding-oracle history.
HashNegotiatedSHA-256 or SHA-384 drives the PRF in 1.2 and HKDF in 1.3.MD5 and SHA-1 combinations are obsolete.
AEADNegotiatedCipher and MAC combine into one authenticated operation.Separate MAC construction opened length-extension and padding oracles.
TLS_AES_128_GCM_SHA256NegotiatedThe TLS 1.3 default suite: AES-128-GCM under SHA-256.Slow without hardware AES instructions.
TLS_CHACHA20_POLY1305_SHA256NegotiatedConstant-time stream cipher for phones and ARM servers.Older clients lack hardware support and negotiate down.