What the padlock icon is really doing
Every time you open an HTTPS page, your browser and the web server perform a brief negotiation before a single byte of content moves. That negotiation is the TLS handshake, and its job is to answer three questions: who are you talking to, how will you encrypt what you say, and how will you prove nobody tampered with the conversation.
HTTPS is simply HTTP running on top of a TLS-secured connection. TLS evolved from Netscape's SSL protocol of the mid-1990s. TLS 1.0 was standardised in RFC 2246 (January 1999), TLS 1.1 in RFC 4346 (April 2006), and TLS 1.2 in RFC 5246 (August 2008). TLS 1.0 and 1.1 were formally deprecated by RFC 8996 in March 2021, after the major browsers removed support in March 2020. Today the internet runs almost entirely on TLS 1.2 and TLS 1.3 — and understanding the handshake means understanding both.
Two kinds of cryptography, two jobs
The handshake leans on two fundamentally different kinds of cryptography, each suited to one of the jobs above.
Asymmetric (public-key) cryptography uses a key pair: a public key anyone can know and a private key that never leaves the server. It is slow, so TLS uses it only for the setup phase — proving identity and agreeing on a shared secret. The workhorse algorithms are RSA and ECDSA for signatures, and (Elliptic-Curve) Diffie-Hellman for key agreement.
Symmetric cryptography uses one shared secret key for both encryption and decryption. It is orders of magnitude faster and handles bulk data, so once the handshake is done, everything — HTTP requests, responses, session cookies — is encrypted with symmetric ciphers such as AES-GCM or ChaCha20-Poly1305. These are AEAD algorithms, providing encryption and data authentication in a single pass.
The handshake's central puzzle is a bootstrap problem: how do two machines that have never spoken agree on a shared secret key over a channel an attacker can read, without ever exposing that key?
Certificates and the chain of trust
Before any encryption happens, your browser needs to answer who am I talking to? The server sends a certificate: a signed bundle containing the domain name, the server's public key, the issuer's identity, and validity dates. Your browser trusts it only if the signature chains up to a root certificate authority (CA) that your operating system or browser ships with.
That chain usually has three links: the leaf certificate for the domain (signed by an intermediate CA), the intermediate CA's certificate (signed by a root CA), and the root CA itself, which is self-signed and pre-installed in your trust store. Your browser walks the chain link by link, verifying each signature with the parent's public key. It also checks that the domain on the leaf matches the site you requested and that the certificate is within its validity window. When the chain fails — an expired certificate, a wrong domain, a self-signed leaf — the browser shows the familiar warning screen and refuses to proceed without an explicit override.
Reading a cipher suite name
Part of the negotiation is agreeing on which algorithms to use. That bundle is called a cipher suite. In TLS 1.2 and earlier, a suite name encodes four ingredients: the key exchange, the authentication method, the bulk cipher, and the hash function. Take one of the most common suites in history:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- ECDHE — ephemeral Elliptic-Curve Diffie-Hellman for the key exchange (more on the “ephemeral” part below).
- RSA — RSA signatures for authenticating the server's certificate.
- AES_128_GCM — AES with a 128-bit key in Galois/Counter Mode for encrypting the session data.
- SHA256 — the SHA-256 hash used in the key derivation.
TLS 1.3 simplified suite names dramatically: they now name only the symmetric cipher and hash, such as TLS_AES_128_GCM_SHA256 or TLS_CHACHA20_POLY1305_SHA256, because TLS 1.3 supports essentially one key exchange model — ephemeral (EC)DH — and signatures are always present. There are only five cipher suites in TLS 1.3, down from hundreds of possibilities in TLS 1.2.
The TLS 1.2 handshake, message by message
The TLS 1.2 full handshake takes two network round trips:
- ClientHello. The client announces the highest TLS version it supports, sends 32 random bytes (the client random), and lists the cipher suites it is willing to use.
- ServerHello. The server picks the TLS version and cipher suite, and sends back its own 32 random bytes.
- Certificate. The server sends its certificate chain so the client can verify its identity.
- ServerKeyExchange / ServerHelloDone. When using ephemeral Diffie-Hellman, the server sends its DH parameters, signed with its certificate's private key, then signals the end of its flight.
- ClientKeyExchange. The client sends its DH public parameter (or, in the older RSA key exchange, a premaster secret encrypted with the server's public key).
- Both sides derive the master secret. Each side combines the client random, server random, and the DH shared secret through a key derivation function — arriving at the same session keys without ever transmitting them.
- Finished (both directions). Each side sends a
Finishedmessage containing a hash of the entire handshake transcript, encrypted with the new session keys. If either transcript hash does not match, the handshake aborts — blocking any man-in-the-middle downgrade to a weaker cipher.
Two round trips may sound trivial, but on a high-latency link they can add hundreds of milliseconds before the first HTTP request.
The TLS 1.3 handshake: one round trip
TLS 1.3, defined in RFC 8446 (August 2018), redesigned the handshake around a simple insight: the client can guess which key agreement algorithm the server will pick and send its key share preemptively, inside the ClientHello.
- ClientHello + key share. The client sends its supported versions and cipher suites, plus one or more Diffie-Hellman key shares for the groups it expects the server to choose.
- ServerHello + key share. The server picks a group the client offered, computes the shared secret immediately, and replies with its own key share. At this point both sides hold the same secret.
- Everything after this is encrypted. The server sends its EncryptedExtensions, Certificate, CertificateVerify signature, and Finished message — all encrypted with keys derived from the shared secret.
- Client Finished. The client verifies the certificate and signature, derives the same keys, and sends its Finished message. Application data follows immediately.
The whole exchange completes in one round trip instead of two. If the client guessed the key agreement group wrong, the server replies with a HelloRetryRequest asking for the right group — a single extra round trip, and the connection still succeeds. TLS 1.3 also removed the insecure baggage of the previous decades: static RSA and DH key exchanges, non-AEAD ciphers, CBC-mode ciphers, RC4, 3DES, compression, renegotiation, and DSA signatures are all gone — and forward secrecy is mandatory.
Forward secrecy: why ECDHE matters
In the older RSA key exchange, the client encrypted the premaster secret with the server's long-term public key. That design had a catastrophic property: if an attacker recorded years of encrypted traffic and later stole the server's private key, they could decrypt everything retroactively.
Ephemeral Diffie-Hellman (the “E” in ECDHE) fixes this. Each connection generates a fresh, throwaway DH key pair. The session keys are derived from those ephemeral values, which are deleted when the connection closes. The long-term private key is used only to sign the handshake (proving identity), never to protect the session keys. Steal the server's private key tomorrow and yesterday's traffic remains undecryptable — this is why server hardening guides insist on ECDHE suites, and why suites without forward secrecy are now deprecated.
Session resumption: skipping the handshake
Returning visitors to a site should not pay the full handshake cost again. The classic approach gives the client a session ticket — an encrypted blob from the server that lets a new handshake reuse the earlier session's secret without redoing the key exchange. The alternative, a session ID, has the server cache the session state and look it up when the client presents the ID.
TLS 1.3 replaced both with a unified pre-shared key (PSK) mechanism: after the first handshake, the server sends the client a PSK derived from that session, and on the next visit the client offers it up. TLS 1.3 goes further with 0-RTT mode, where the client can send encrypted application data in its very first message using the resumption secret — but the RFC flags a caveat: 0-RTT data is replayable, so it should never carry non-idempotent operations like form submissions or payments.
Inspecting a handshake yourself
The best way to internalise all of this is to watch it happen:
openssl s_client -connect rubeshan.com:443 -servername rubeshan.com
In the output, look for the Protocol line (the negotiated TLS version) and the Cipher line (the negotiated cipher suite). Add -showcerts to see the full certificate chain.
You can see the same information in your browser. In Chrome or Firefox, open DevTools, go to the Security tab (Chrome) or the Network tab's security details (Firefox), and reload the page: it shows the negotiated protocol version, cipher suite, and the certificate's issuer.
Further reading
- RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 — the definitive specification, published August 2018.
- What Happens in a TLS Handshake? — Cloudflare's walkthrough of the handshake message flow for RSA and ephemeral Diffie-Hellman key exchanges.
- An Overview of TLS 1.3 and Q&A — Cloudflare's deep dive into why TLS 1.3 drops a round trip and encrypts the handshake after the ServerHello.
- Mozilla Server Side TLS — Mozilla's guidance on which TLS versions and cipher suites to configure on your own servers.
