Skip to content
pwnsy
cryptographyintermediate#tls#handshake#encryption#key-exchange#https

How the TLS 1.3 Handshake Works

A plain walkthrough of the TLS 1.3 handshake: key exchange, certificates, and how a browser and server agree on session keys in one round trip.

Every time a padlock appears in a browser, two computers that have never spoken before have just agreed on a set of secret keys, in the open, while anyone on the network could be listening. That agreement is the TLS handshake. It is the part of HTTPS that turns a public connection into a private one, and TLS 1.3 made it faster and simpler than any version before it.

This guide walks through the TLS 1.3 handshake message by message: what each side sends, how they arrive at shared keys without ever transmitting them, and how the client knows it is talking to the real server rather than an impostor.

What the handshake has to achieve

Before any application data moves, the handshake solves three problems at once.

The first is key agreement. Both sides need the same secret keys to encrypt traffic, and they have to reach those keys without an eavesdropper learning them. The second is authentication. The client needs proof that the server is who it claims to be, so an attacker cannot sit in the middle and impersonate the destination. The third is negotiation. The two sides must agree on which cipher and hash to use, from the set they both support.

TLS 1.3 does all three in a single round trip. The client speaks, the server answers, and the connection is ready.

The messages, in order

Here is the full exchange for a fresh TLS 1.3 connection.

StepSenderMessagePurpose
1ClientClientHelloOffers cipher suites, supported groups, and a key share
2ServerServerHelloPicks the cipher suite and sends its own key share
3ServerEncryptedExtensionsAdditional parameters, now encrypted
4ServerCertificateThe server's certificate chain
5ServerCertificateVerifyA signature proving it holds the certificate's private key
6ServerFinishedA check value over the whole handshake
7ClientFinishedThe client's matching check value

After step 2, everything is encrypted. That is a meaningful change from earlier versions, where the certificate travelled in clear.

Step 1: ClientHello carries a key already

The old TLS 1.2 handshake wasted a round trip asking the server which parameters it preferred before either side committed to a key. TLS 1.3 makes an assumption instead. The client guesses which key exchange group the server will accept, usually a modern elliptic curve, and sends its Diffie-Hellman public key share in the very first message.

The ClientHello includes the TLS version, a random value, the list of cipher suites the client supports, the supported key exchange groups, and one or more key shares. If the client guesses the group correctly, the handshake finishes in one round trip. If it guesses wrong, the server asks it to retry with a supported group, which costs an extra round trip but is rare in practice.

Step 2: ServerHello and the shared secret

The server reads the ClientHello, picks a cipher suite it supports, and replies with its own random value and its own Diffie-Hellman key share.

At this exact moment, both sides have what they need. The client has its own private key and the server's public share. The server has its own private key and the client's public share. Each side combines its private key with the other's public key and computes the identical shared secret. That value was never sent across the network. An eavesdropper who captured every byte saw two public shares, and public shares alone do not reveal the secret. This is the heart of Diffie-Hellman, covered in How Diffie-Hellman Works.

Because the key shares are ephemeral, generated fresh for this one connection and discarded afterward, the session gets forward secrecy. Even if the server's long-term private key leaks next year, this recorded session stays unreadable. See Perfect Forward Secrecy Explained.

The secret is derived, never sent

The Diffie-Hellman output is not used directly as the encryption key. TLS 1.3 runs it through a key schedule built on HKDF, which mixes in the handshake transcript and produces separate keys for the handshake and for application data. The keys both sides use are computed independently at each end and match exactly, without any key material crossing the wire.

Steps 3 to 6: the server proves who it is

Shared keys stop eavesdropping, but on their own they do not stop impersonation. An attacker could complete a perfectly good key exchange while pretending to be your bank. Authentication closes that gap.

The server sends its Certificate, a chain that ends at a root certificate authority the client already trusts. The certificate binds a public key to a domain name and is signed by the authority. This is the same trust model described in What Is PKI.

The certificate alone is not enough, because anyone can copy a public certificate. So the server also sends CertificateVerify: a digital signature, made with the certificate's private key, over a hash of the handshake so far. Only the holder of that private key could produce the signature, and the client checks it against the public key in the certificate. If it verifies, the server has proven it owns the name in the certificate.

The server's Finished message follows, a keyed hash over the entire handshake transcript. It confirms that nothing in the exchange was tampered with in transit.

Step 7: the client confirms

The client validates the certificate chain, checks the signature, verifies the server's Finished value, and sends its own Finished message. From that point, both sides encrypt application data with the derived keys. The whole visible cost to the user was one round trip.

Negotiation and downgrade protection

TLS has to work across a huge range of clients and servers, so the two sides agree on parameters rather than assuming them. The ClientHello advertises every cipher suite and key exchange group the client supports, and the server picks one it also supports. In TLS 1.3 the menu is deliberately short. The old versions accumulated dozens of cipher suites, many of them weak, and picking badly was a common source of insecure connections. TLS 1.3 kept only a small set of strong, forward-secret suites, which removes a whole class of misconfiguration.

Negotiation across an open network invites a specific attack: an active attacker sitting between the two sides could tamper with the ClientHello to strip out the strong options and force a fallback to something weak, a downgrade attack. TLS 1.3 defends against this in two ways. The Finished messages are keyed hashes over the entire handshake transcript, so any tampering with the earlier messages makes the Finished check fail and the connection abort. TLS 1.3 also embeds a sentinel value in the server's random so that a client which supports 1.3 can detect a forced downgrade to an older version. The result is that the handshake either completes with parameters both sides genuinely chose, or it fails loudly.

Session resumption and 0-RTT

TLS 1.3 can skip most of this work for a returning client. After a successful handshake, the server can issue a session ticket. On the next visit, the client presents the ticket and derives keys from a pre-shared secret established earlier, avoiding a fresh certificate exchange.

TLS 1.3 also allows 0-RTT, where the client sends application data in its very first message, using keys from the resumed session. It is fast, and it carries one specific caveat.

0-RTT data can be replayed

Data sent in a 0-RTT early-data flight has weaker guarantees than the rest of the connection. An attacker who captures it can resend it, and the server may process it twice. Restrict 0-RTT to requests that are safe to repeat, such as idempotent reads, and never use it for actions that change state like payments or account edits.

Checking a TLS deployment

If you run a service, a handful of practical steps keep the handshake healthy.

  1. Enable TLS 1.3 and disable everything below TLS 1.2. TLS 1.0 and 1.1 are deprecated and should be off. Follow the version guidance in NIST SP 800-52.
  2. Prefer forward-secret cipher suites. In TLS 1.3 every suite is forward secret, which is one more reason to prefer it.
  3. Keep the certificate chain complete and current. Serve the full chain, watch expiry dates, and automate renewal so a lapsed certificate never breaks the handshake.
  4. Handle 0-RTT with care, or leave it off. Only enable early data if your application layer can tolerate replays.
  5. Test from outside. Scan the endpoint from a separate network to confirm the negotiated version, cipher, and chain match what you intended.

Live vulnerability data helps here too. When a flaw hits a TLS library or a certificate authority, our Exploit Intelligence dashboard tracks which of those issues are actually being exploited, so patching a handshake-facing component becomes a decision backed by evidence rather than a guess.

A worked example: one connection from hello to data

It helps to trace a single connection in concrete terms. Imagine a browser opening https://example.test for the first time, with no prior session to resume.

The browser builds a ClientHello. It sets the record layer to advertise TLS 1.0 for backward compatibility with old middleboxes, then uses a supported_versions extension to state that it actually wants TLS 1.3. This split exists because some network appliances break when they see an unfamiliar version number in the record header, so TLS 1.3 disguises itself at the outer layer and declares its real intent in an extension. The ClientHello also carries a 32-byte random value, a list of cipher suites such as TLS_AES_128_GCM_SHA256, a supported_groups extension listing curves like x25519 and secp256r1, and a key_share extension holding a fresh ephemeral public key for the group the browser expects the server to accept.

The server receives this and makes its choices. It selects a cipher suite from the browser's list, picks a group that both sides support, and generates its own ephemeral key pair for that group. It sends a ServerHello containing its random value, the chosen suite, and its own key_share. From this instant, both parties can compute the same Diffie-Hellman shared secret. The server derives handshake traffic keys immediately and encrypts everything that follows.

The server then sends EncryptedExtensions with parameters that do not affect key agreement, such as the negotiated application protocol from ALPN. It sends Certificate, carrying its leaf certificate for example.test plus any intermediate certificates needed to chain to a trusted root. It sends CertificateVerify, a signature over a transcript hash of every handshake message so far, produced with the private key that matches the certificate. It sends Finished, an HMAC over the transcript keyed by a secret derived from the handshake.

The browser verifies the certificate chain, checks that the certificate covers example.test, confirms the signature in CertificateVerify, and validates the server Finished. It sends its own Finished. Both sides now derive the application traffic keys and the encrypted HTTP request goes out. The user saw a page load. Underneath, a full mutual setup of confidentiality, integrity, and server authentication completed in one round trip.

The key schedule in more detail

The single most misunderstood part of TLS 1.3 is how raw Diffie-Hellman output becomes the keys that protect traffic. The protocol never uses the shared secret directly. It runs a key schedule built on HKDF, the HMAC-based key derivation function, which takes input keying material and produces many independent, purpose-bound keys from it.

The schedule proceeds in stages. It begins with an Early Secret, derived from a pre-shared key if one exists or from a block of zeros if not. It mixes in the Diffie-Hellman shared secret to produce a Handshake Secret, from which the handshake traffic keys come. Those keys protect everything after the ServerHello, including the certificate. Finally it derives a Master Secret, and from that the application traffic keys that protect the actual HTTP data.

Two design choices matter here. First, each key is bound to a label and to the running transcript hash, so a key derived for one purpose can never be substituted for another, and any tampering with earlier messages changes the transcript and breaks every later key. Second, the schedule supports key updates during a long-lived connection, so a session that moves a large amount of data can rotate its traffic keys without a new handshake. The HKDF construction is deliberately conservative, and it is one reason TLS 1.3 has resisted the key-recovery weaknesses that troubled older key derivation approaches.

How the handshake evolved

TLS 1.3 did not appear from nothing. It is the result of hard lessons from every earlier version.

SSL 2.0 and 3.0, the ancestors of TLS, allowed weak ciphers and had structural flaws that made them unsafe. TLS 1.0 and 1.1 tightened things but still permitted a static RSA key exchange, where the client encrypted a secret under the server's long-term public key. That design had a fatal property: anyone who recorded the traffic and later obtained the server's private key could decrypt every past session, because there was no forward secrecy. TLS 1.2 added modern authenticated ciphers and better hashing, and it allowed ephemeral Diffie-Hellman, but it still carried the old options alongside the new ones, and it needed two round trips to complete.

TLS 1.3 made the decisions the earlier versions left open. It removed static RSA key exchange entirely, so every session now has forward secrecy. It removed the weak ciphers, the renegotiation feature that had caused security bugs, and compression, which had enabled data-leak attacks. It moved the certificate behind encryption. It collapsed the handshake to one round trip by having the client send a key share up front. The through-line across all of it is that the protocol stopped offering choices that could be chosen badly.

TLS 1.3 versus TLS 1.2 at a glance

PropertyTLS 1.2TLS 1.3
Round trips for a fresh handshakeTwoOne
Forward secrecyOptional, depends on cipher suiteAlways, every suite
Static RSA key exchangeAllowedRemoved
Certificate visibilitySent in the clearEncrypted after ServerHello
Cipher suite menuLarge, includes weak optionsSmall, strong suites only
RenegotiationPresent, source of past bugsRemoved
Zero round-trip dataNot availableAvailable with replay caveats

The pattern is a smaller, stricter protocol that is faster and harder to misconfigure.

Detection signals: watching handshakes on the wire

Even though the certificate and most of the handshake are encrypted in TLS 1.3, several observable signals still carry meaning for defenders and operators.

The ClientHello remains in the clear, and its contents form a fingerprint. The ordered list of cipher suites, extensions, and supported groups tends to be consistent for a given client library, so unusual combinations can flag automated tools or malware that ships its own TLS stack rather than using the host's. Fingerprinting techniques such as JA3 and its successors are built on exactly this.

The Server Name Indication in the ClientHello reveals the destination domain unless Encrypted Client Hello is in use, so passive monitoring can still see which sites a host reached even when it cannot read the traffic. A sudden appearance of connections that use raw IP addresses with no SNI, or that negotiate old versions, can indicate tooling that is trying to avoid inspection.

A handshake that ends in a HelloRetryRequest tells you the client guessed the key exchange group wrong. A small number of these is normal. A flood of them from one source can indicate a misconfigured or probing client. Alerts on negotiated protocol versions below TLS 1.2, on self-signed or untrusted certificate chains inside your environment, and on certificates whose names do not match the requested SNI all catch common misconfigurations and some interception attempts.

Log the negotiated version and cipher

Servers and reverse proxies can record the TLS version and cipher suite chosen for each connection. Feeding those logs into your monitoring lets you spot clients still using deprecated versions before you enforce a cutoff, and it turns a later decision to disable TLS 1.1 into a measured change rather than a guess about who might break.

Common misconceptions

A few beliefs about the handshake are worth correcting directly.

The first is that the encryption key is sent to the server in encrypted form. It is not. In TLS 1.3 the key is never transmitted at all. Both sides derive it independently from the Diffie-Hellman exchange, which is the entire point of using Diffie-Hellman.

The second is that a valid certificate means the site is safe. The certificate proves only that the server controls the private key for the name in the certificate. A criminal who registers a lookalike domain can obtain a perfectly valid certificate for it. The handshake authenticates the domain, and judging whether the domain is trustworthy is a separate human decision.

The third is that TLS 1.3 hides everything. The ClientHello, including the SNI in the common case, is visible. The size and timing of encrypted records can leak information about the content. TLS protects the contents of the conversation and proves the server's identity. It does not make the fact of the connection invisible.

The fourth is that zero round-trip resumption is free. Early data traded for that speed has weaker replay guarantees, and using it for anything that changes state is a mistake.

Frequently asked questions

Does TLS 1.3 authenticate the client as well as the server? By default it authenticates only the server. The client can be authenticated too, using a client certificate, which the server requests during the handshake. This mutual TLS is common inside service-to-service architectures and less common for ordinary web browsing, where the user proves identity at the application layer after the tunnel is up.

Why does the ClientHello pretend to be an older version at the record layer? Some older network middleboxes inspect the version field in the record header and drop connections that carry a version they do not recognize. To survive those boxes, TLS 1.3 leaves the outer version looking like TLS 1.2 and signals its real version inside the supported_versions extension, which the middleboxes ignore.

What happens if the client guesses the wrong key exchange group? The server responds with a HelloRetryRequest naming a group it does support, and the client sends a new ClientHello with a key share for that group. This costs one extra round trip. Because clients pick widely supported groups such as x25519 by default, retries are uncommon.

Is the certificate really encrypted in TLS 1.3? Yes. After the ServerHello, both sides have handshake traffic keys, and the Certificate and CertificateVerify messages travel under that encryption. In TLS 1.2 the certificate was sent in the clear, so a passive observer could see which certificate a server presented. TLS 1.3 hides that metadata.

How does the handshake stop a replay of recorded messages? Each side contributes a fresh random value and a fresh ephemeral key, so the derived keys differ on every connection. Replaying a recorded handshake produces keys the attacker cannot compute. The Finished messages, keyed by the handshake secret, also confirm that both sides saw the identical transcript.

Does a faster handshake mean weaker security? No. The single round trip comes from sending the key share early, not from cutting cryptographic steps. TLS 1.3 is both faster and stronger than TLS 1.2, because the speedup and the security improvements come from the same simplification.

What is the practical difference between a session ticket and a fresh handshake? A session ticket lets a returning client derive keys from a secret established earlier, skipping the certificate exchange and the full key agreement. It is faster and lighter on the server. The tradeoff is that resumed sessions, and especially zero round-trip early data, carry weaker replay properties than a full fresh handshake, so state-changing requests should wait for the full connection.

The TLS 1.3 handshake packs key agreement, authentication, and negotiation into a single exchange that most users never notice. Understand the seven messages, and the padlock stops being magic and becomes a mechanism you can reason about, deploy correctly, and defend.

Sources & further reading

Sharetwitterlinkedin

Related guides