The TLS handshake isn’t about encrypting your data; it’s about agreeing on how to encrypt your data, and it’s a lot more involved than you probably think.
Let’s watch it happen. Imagine you’re curl trying to talk to a web server at example.com.
curl -v https://example.com
The -v (verbose) flag is key here. It makes curl spill its guts about what’s happening during the handshake. You’ll see lines like:
* Trying 93.184.216.34:443...
* Connected to example.com (93.184.216.34) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client Hello (1):
...
* TLSv1.3 (IN), TLS handshake, Server Hello (2):
...
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
...
* TLSv1.3 (IN), TLS handshake, Certificate (11):
...
* TLSv1.3 (IN), TLS handshake, Certificate Verify (13):
...
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
This is the dance. The client (your curl) starts by saying "Hello!" and offering what it can do.
1. Client Hello: curl sends a Client Hello message. This is like the client walking up to the server and saying, "Hey, I want to talk securely. Here’s what I speak (TLS versions like 1.2 or 1.3), here are the encryption ciphers I support (like AES-GCM), and here’s a random number I just generated (client random)." It also includes information about supported extensions, like ALPN (Application-Layer Protocol Negotiation), which lets the client and server agree on protocols like HTTP/2 or HTTP/1.1.
2. Server Hello: The server (example.com) receives the Client Hello and picks the best match from the client’s list. It sends back a Server Hello message. This includes the chosen TLS version, the cipher suite it’s going to use, its own random number (server random), and a session ID (if it wants to resume a previous session). Crucially, it also signals its choice for ALPN.
3. Certificate: The server then sends its digital certificate. This is the server’s ID card, signed by a trusted Certificate Authority (CA). It contains the server’s public key and other identifying information. curl checks if this certificate is valid, hasn’t expired, and was issued by a CA it trusts. If it’s not, you’ll get a scary browser warning.
4. Server Key Exchange (Optional): If the chosen cipher suite requires it, the server might send additional information to help the client verify its identity or establish a shared secret. This is less common in TLS 1.3.
5. Certificate Request (Optional): Sometimes, the server might ask the client to present its own certificate for mutual authentication. This is rare for regular web browsing but common in enterprise or VPN scenarios.
6. Server Hello Done: The server signals it’s finished sending its initial handshake messages.
7. Client Key Exchange: Now, the client needs to establish a shared secret key that only it and the server will know. This is where the public key from the server’s certificate comes into play. The client uses the server’s public key to encrypt a pre-master secret (another random number generated by the client). Only the server, with its corresponding private key, can decrypt this.
8. Change Cipher Spec: The client sends a Change Cipher Spec message, indicating that all subsequent messages will be encrypted using the newly negotiated session keys.
9. Finished: The client sends its first encrypted message, a Finished message, which is a hash of all the handshake messages exchanged so far. This confirms that the handshake process was successful and that the client has successfully decrypted the pre-master secret and derived the session keys.
10. Server Change Cipher Spec & Finished: The server receives the encrypted Finished message, decrypts it, verifies the hash, and then sends its own Change Cipher Spec and Finished message. This confirms to the client that the server also successfully derived the session keys and is ready to communicate securely.
After this, the handshake is complete. All subsequent application data (like your HTTP requests and the web page content) is encrypted using the session keys established during the handshake.
The most surprising thing about the TLS handshake is how much of it is dedicated to proving identity and agreeing on encryption methods before any actual application data is sent. It’s a meticulous negotiation to ensure that the subsequent encrypted communication is both authenticated and confidential.
The curl -v output often shows ALPN negotiation. It’s a TLS extension that allows the client and server to negotiate which application protocol they’ll use over the secure TLS connection. Common examples are http/1.1 and h2 (for HTTP/2). The client offers a list of protocols it supports, and the server picks one from that list. If the server doesn’t support any of the client’s offered protocols, the connection might fail or fall back to a default.
The next thing you’ll typically see after a successful handshake is the actual HTTP request and response, all now framed by the secure channel.