Security Analysis

The TLS Handshake Explained

What happens in the milliseconds between typing a URL and seeing a secure connection, and why it matters for performance and security

SiteSecurityScore Team·10 min read·Updated Feb 20, 2026
Network server connections representing TLS handshake process

What is the TLS Handshake? #

The TLS handshake is the negotiation process that happens at the very beginning of every HTTPS connection, before any application data (like an HTML page or API response) is exchanged. It takes place after the TCP connection is established and typically completes in tens of milliseconds, though the exact time depends on network latency and the TLS version in use.

The handshake accomplishes three things. First, it authenticates the server by verifying its digital certificate against the browser's list of trusted Certificate Authorities (CAs), the organizations authorized to issue certificates. Second, it negotiates a cipher suite, the specific combination of algorithms that will be used for encryption, authentication, and data integrity during the session. Third, it establishes a shared secret key that both sides use to encrypt and decrypt the data that follows.

Understanding the handshake matters for two reasons. From a security perspective, the handshake determines which encryption algorithms protect the connection. A misconfigured server that accepts weak cipher suites or outdated protocol versions opens the door to attacks. From a performance perspective, the handshake adds latency before the first byte of content can be sent. TLS 1.3 was designed specifically to reduce this overhead.

The TLS 1.2 Handshake Step by Step #

TLS 1.2 uses a two-round-trip handshake. Each round trip (RTT) means data must travel from the client to the server and back. On a connection with 50ms of latency, two round trips add roughly 100ms before any page content can start loading.

1

ClientHello

The browser sends a message to the server listing the TLS versions it supports, a random number (used later for key generation), and a list of cipher suites it can use, ordered by preference.

2

ServerHello + Certificate

The server responds with the TLS version and cipher suite it selected from the client's list, its own random number, and its digital certificate. The certificate contains the server's public key and is signed by a CA that the browser trusts.

3

Key Exchange

The browser verifies the certificate, then both sides perform a key exchange. With ECDHE (Elliptic Curve Diffie-Hellman Ephemeral), each side generates a temporary key pair and exchanges public values. Both sides then independently compute the same shared secret without ever sending it over the network.

4

Change Cipher Spec + Finished

Both sides signal that they are switching to encrypted communication using the negotiated cipher suite and shared key. Each sends a "Finished" message encrypted with the new key, which the other side decrypts to verify that the handshake was not tampered with.

5

Application Data

The connection is now encrypted. The browser sends the HTTP request (for example, GET /index.html) and the server responds with the page content. All data from this point forward is encrypted with the session key.

Latency cost

The TLS 1.2 handshake requires 2 round trips (2-RTT) before data can flow. On a mobile connection with 100ms latency, this adds 200ms just for the handshake. For users on distant servers or slow networks, this overhead is noticeable. TLS 1.3 cuts this in half.

TLS 1.3: A Faster Handshake #

TLS 1.3 redesigned the handshake to complete in a single round trip (1-RTT). The client sends its key share in the very first message (ClientHello), so the server can compute the shared secret immediately and respond with encrypted data. This saves one full round trip compared to TLS 1.2.

The speed improvement comes from removing options. TLS 1.3 dropped support for RSA key exchange (which does not provide forward secrecy), removed older cipher suites, and eliminated the separate "Change Cipher Spec" step. By mandating a smaller set of strong algorithms, the protocol can combine steps that were previously separate.

TLS 1.3 also supports 0-RTT resumption, which allows a client that has previously connected to the server to send application data in the very first message, before the handshake completes. This eliminates the handshake latency entirely for returning visitors. However, 0-RTT data can be replayed by an attacker who captures it, so it should only be used for idempotent requests (like loading a page), never for state-changing operations like form submissions or API writes.

What TLS 1.3 Removed

  • RSA key exchange (no forward secrecy)
  • CBC mode ciphers (vulnerable to padding oracle attacks)
  • SHA-1 hash function
  • Compression (CRIME attack vector)

What TLS 1.3 Mandates

  • Forward secrecy on every connection (ECDHE)
  • AEAD ciphers only (AES-GCM, ChaCha20-Poly1305)
  • 1-RTT handshake (half the latency of TLS 1.2)
  • Encrypted handshake messages (server certificate is hidden)

0-RTT replay risk

0-RTT early data can be captured and replayed by an attacker. If a POST request or API call with side effects is sent as 0-RTT data, it could be executed multiple times. Most web servers and CDNs that support 0-RTT only allow it for GET requests to mitigate this risk. If your application processes 0-RTT data, ensure it only handles safe, idempotent operations.

How TLS Cipher Suite Negotiation Works #

During the ClientHello message, the browser sends an ordered list of cipher suites it supports. The server compares this list against its own configured cipher suites and selects the best match. The selected suite determines the algorithms used for the remainder of the connection.

Most server software lets you control two things: which cipher suites are available, and whether the server's preference order or the client's preference order takes priority. The ssl_prefer_server_ciphers directive in Nginx (and its Apache equivalent SSLHonorCipherOrder) controls this. When enabled, the server picks its most preferred cipher that the client also supports, giving you control over which algorithm is used.

In TLS 1.3, cipher negotiation is simpler because the protocol only allows five cipher suites, all of which are strong. There is no risk of a client or server accidentally selecting a weak option. For TLS 1.2 connections, you should explicitly list the allowed cipher suites in your server configuration and disable any that use RC4, DES, 3DES, or static RSA key exchange.

Nginx cipher configuration
# Strong cipher suite configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; # Let client choose in TLS 1.3
Apache cipher configuration
# Strong cipher suite configuration SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder off

Forward Secrecy in the Handshake #

Forward secrecy (also called perfect forward secrecy or PFS) is a property of the key exchange that ensures past sessions remain secure even if the server's long-term private key is later compromised. It works by using ephemeral (temporary) keys for each connection rather than the server's permanent key.

With ECDHE (Elliptic Curve Diffie-Hellman Ephemeral), both the client and server generate a fresh key pair for each handshake. They exchange public values, and both independently compute the same shared secret using elliptic curve math. After the handshake, the ephemeral private keys are discarded. If an attacker records the encrypted traffic and later obtains the server's long-term RSA or ECDSA key, they still cannot derive the session keys because those were generated from the ephemeral key pairs, not the long-term key.

Without forward secrecy (for example, with plain RSA key exchange used in older TLS 1.2 configurations), the session key is encrypted with the server's public key. Anyone who obtains the private key can decrypt every recorded session, past and future. This is why TLS 1.3 mandates ECDHE and does not allow RSA key exchange at all.

Why this matters in practice

Organizations like intelligence agencies and large ISPs can store encrypted traffic at scale. If they obtain a server's private key years later (through a breach, legal order, or key rotation lapse), forward secrecy ensures that all previously recorded sessions remain unreadable. This is not a theoretical concern. It is the explicit threat model that forward secrecy was designed to address.

Observing the Handshake in Practice #

You can see the handshake results using browser tools, command-line utilities, or network analysis software. Each gives you a different level of detail.

Browser DevTools Security Tab

In Chrome or Edge, open Developer Tools (F12), click the Security tab, and select the main origin. You will see the TLS version, cipher suite, key exchange algorithm, and certificate details. This is the quickest way to verify what your browser actually negotiated with the server.

  • Protocol: should show TLS 1.2 or TLS 1.3
  • Key exchange: should include ECDHE for forward secrecy
  • Cipher: should use AES-GCM or ChaCha20

OpenSSL s_client

The openssl s_client command connects to a server and displays the full handshake details, including the negotiated protocol, cipher suite, and certificate chain.

OpenSSL handshake inspection
# Connect and show handshake details openssl s_client -connect example.com:443 # Key output to look for: # Protocol : TLSv1.3 # Cipher : TLS_AES_256_GCM_SHA384 # Server certificate chain # Verify return code: 0 (ok)

Wireshark (Packet-Level Analysis)

For the deepest visibility, Wireshark can capture and display every packet in the TLS handshake. Filter by tls.handshake to see the ClientHello, ServerHello, certificate exchange, and key exchange messages individually. This is useful for debugging handshake failures or verifying that your server does not offer deprecated protocol versions. Note that in TLS 1.3, the server certificate is encrypted and will not appear in the packet capture unless you have the session keys.

Was this helpful?
Share

Check Your TLS Handshake Configuration

Scan your website to verify TLS version, cipher suites, forward secrecy, and certificate chain in one report.