Home / 524 / The secret that never crosses the wire: Diffie-Hellman and TLS 1.3’s silent negotiation

The secret that never crosses the wire: Diffie-Hellman and TLS 1.3’s silent negotiation

Ilustración del cifrado TLS 1.3 y el intercambio de claves Diffie-Hellman

Every time you open an HTTPS page, the same little miracle repeats itself in a few milliseconds: two machines that have never met must agree on a shared secret while a third party listens to the whole conversation. That silent pact is called a key exchange, and at the heart of the modern web it is solved by a mathematical scheme from the seventies: Diffie-Hellman.

The dilemma of the key you must hand to the enemy

Symmetric cryptography — the kind that uses the same key to encrypt and decrypt, like AES — is lightning fast, but it demands that sender and receiver hold the same secret. And here is the chicken-and-egg problem: if two computers do not know each other, how do they share a key without letting the attacker listening in the middle capture it during the trip? Sending it in clear text is handing the key to the very person you are trying to spy on — the one whose snooping you wanted to stop.

The first answer was asymmetry: each party holds a pair of keys (RSA, for instance), one public and one private. The client encrypts the session key with the server’s public key, and only the server’s private key can open it. It works, but it carries a serious flaw: if years later someone steals the server’s private key, they can retroactively decrypt all the traffic recorded today. It is the nightmare of “record now, decrypt later,” and the reason TLS 1.3 removed classic RSA key exchange entirely.

Diffie-Hellman: the number nobody sees but everyone shares

Diffie-Hellman attacks the problem head-on: both parties produce the same secret without ever sending it. The trick is modular exponentiation. They publicly agree on two numbers, a huge prime p and a base g. The client picks a secret exponent a and sends g^a mod p; the server picks its own b and sends g^b mod p. Now each raises what it received to its own secret: the client computes (g^b)^a = g^(ab), and the server computes (g^a)^b = g^(ab). Same result, and that value g^(ab) mod p is the shared key.

The interesting part is what the spy sees: only g^a and g^b. To rebuild g^(ab) it would have to recover a from g^a — that is, solve the discrete logarithm, a problem with no known efficient method when p is hundreds of digits long. That is why both parties are said to share a secret that never crossed the wire: it only exists inside each one’s own computation.

ECDHE and the ephemeral secret

In practice, TLS 1.3 does not use Diffie-Hellman over plain integers but its elliptic-curve version: ECDHE (Elliptic Curve Diffie-Hellman Ephemeral). Instead of modular exponentiation over primes, it works with points on a curve such as X25519 or P-256, and the equivalent operation is scalar point multiplication. The advantage is the size ratio: a 256-bit elliptic-curve key offers security comparable to a 3072-bit Diffie-Hellman, so the handshake fits in tiny packets and runs faster.

The “E” in ephemeral is the whole point. On every new connection, client and server generate a fresh key pair that is destroyed as soon as the session ends. Because the shared secret was derived from ephemeral material, even if an attacker captures the traffic today and steals the server’s private key in ten years, they cannot decrypt what was recorded: the material it was encrypted with no longer exists. This is called forward secrecy, and it is one of the reasons TLS 1.3 dropped cryptosystems that could not guarantee it.

The certificate: the signature that blocks the impostor

Diffie-Hellman solves the secret exchange, but it leaves an awkward question: when g^b arrives, is it really from the server you called, or from an impostor in the middle? That is what the certificate is for. The server signs its ephemeral public key with the private key of its certificate, and the client verifies that signature with the public key of the root certificate authority, which it already trusts because it is installed on its system. The chain of trust turns an anonymous channel into a verified identity: it is not enough that the secret be undecipherable — it also has to belong to who you think it is.

The handshake in a single round trip

All this scaffolding now fits in one round trip. On the first flight, the ClientHello already carries the client’s ephemeral public key in the key_share extension; the server replies with its ServerHello and its own key. Both derive the shared secret with a key derivation function (HKDF), which stretches the random material into the independent encryption and authentication keys for each direction. The established connection starts encrypting immediately, with no extra round trips beyond the strictly necessary: the client can send its first encrypted request right after receiving the ServerHello.

Compared with the pair of round trips TLS 1.2 required, this one-way design is clearly noticeable: on high-latency networks — satellite, 4G/5G at the edge, transoceanic crossings — it recovers tens of milliseconds on every new connection. And for session resumption there is even 0-RTT, which anticipates the secret from a previous session and sends encrypted data in the very first packet, at the cost of accepting replay risk, so it is reserved for safe and idempotent requests.

A pact that nobody listens to

Behind that green padlock there is, ultimately, half-century-old mathematics renewed by the cutting edge of elliptic curves. The two parties have never met, never shared the key, and yet they speak in a code that only they understand — one that not even a server betrayed years later can reopen. Next time you see a padlock in the address bar, remember: every millisecond of that connection rests on a secret that never crossed the wire.