Key Exchange — Diffie-Hellman and ECDHE
Alice and Bob are on the internet. Eve is listening to every single packet. Alice and Bob need to agree on a shared secret — an AES key — so they can encrypt their communication. But every message between them is visible to Eve.
This sounds impossible. If Alice sends the key to Bob, Eve gets it. If Bob sends it to Alice, Eve gets it. Any message they exchange is compromised.
In 1976, Whitfield Diffie and Martin Hellman published a protocol that solves this seemingly impossible problem. Two parties can agree on a shared secret over a completely public channel, and an eavesdropper who sees every message cannot compute the secret. This is the Diffie-Hellman key exchange, and it is the foundation of every TLS connection in your Kubernetes cluster.
Part 1: The Paint Mixing Analogy
Before the math, here is the intuition. Imagine Alice and Bob agree on a shared color using paint, with Eve watching.
- Alice and Bob publicly agree on a base color: yellow. Eve sees this.
- Alice picks a secret color: red. She mixes it with yellow to get orange. She sends orange to Bob. Eve sees orange.
- Bob picks a secret color: blue. He mixes it with yellow to get green. He sends green to Alice. Eve sees green.
- Alice takes Bob's green and mixes in her secret red. She gets brown.
- Bob takes Alice's orange and mixes in his secret blue. He gets brown.
Alice and Bob now share brown — and Eve, who saw yellow, orange, and green, cannot unmix the paints to figure out brown.
The Diffie-Hellman key exchange works because mixing is easy but un-mixing is hard. In the real protocol, "mixing" is modular exponentiation (raising a number to a power, modulo a prime). Computing the forward direction is fast. Computing the reverse (the discrete logarithm) is computationally infeasible for large numbers. This asymmetry between the forward and reverse operations is what makes DH secure.
The critical property: Alice and Bob arrive at the same shared secret without ever transmitting it. The secret is computed, not communicated.
Part 2: The Mathematics (Simplified)
The real Diffie-Hellman protocol uses modular arithmetic instead of paint:
Public parameters (known to everyone, including Eve):
p = a large prime number (2048+ bits)
g = a generator (small number, typically 2 or 5)
Alice:
1. Picks a secret random number: a
2. Computes: A = g^a mod p
3. Sends A to Bob (public)
Bob:
1. Picks a secret random number: b
2. Computes: B = g^b mod p
3. Sends B to Alice (public)
Alice computes the shared secret:
secret = B^a mod p = (g^b)^a mod p = g^(ab) mod p
Bob computes the shared secret:
secret = A^b mod p = (g^a)^b mod p = g^(ab) mod p
Both get: g^(ab) mod p — the same value!
Eve knows: p, g, A = g^a mod p, B = g^b mod p
Eve needs: a or b (to compute g^(ab) mod p)
Finding a from g^a mod p is the Discrete Logarithm Problem — infeasible for large p.
Diffie-Hellman Key Exchange
Click each step to explore
In TLS, the DH public parameters (the prime p and generator g) are not negotiated from scratch. TLS uses standardized DH groups with well-chosen primes (RFC 7919 for finite-field DH, or named curves like X25519 for ECDHE). This means the "agree on public parameters" step is really just both sides saying "let us use X25519" in the ClientHello/ServerHello messages.
A Concrete (Small) Example
p = 23 (small prime, for illustration — real DH uses 2048+ bit primes)
g = 5 (generator)
Alice:
a = 6 (secret)
A = 5^6 mod 23 = 15625 mod 23 = 8
Sends A = 8 to Bob
Bob:
b = 15 (secret)
B = 5^15 mod 23 = 30517578125 mod 23 = 19
Sends B = 19 to Alice
Alice computes shared secret:
secret = 19^6 mod 23 = 47045881 mod 23 = 2
Bob computes shared secret:
secret = 8^15 mod 23 = 35184372088832 mod 23 = 2
Shared secret = 2 ✓
Eve knows: p=23, g=5, A=8, B=19
Eve needs to find: a such that 5^a mod 23 = 8
With p=23 this is trivial (a=6). With p being 2048 bits, it is infeasible.
Part 3: Forward Secrecy — Why Ephemeral Keys Matter
Classic Diffie-Hellman has a weakness: if Alice and Bob reuse their secret values (a and b) across multiple sessions, and an attacker later compromises one of those values, all past sessions are decrypted.
Forward secrecy (also called perfect forward secrecy) means that compromising long-term keys does not compromise past session keys. Each session uses fresh, random, ephemeral key pairs that are discarded after use.
Forward secrecy is the property that past encrypted communications remain secure even if the server's private key is compromised in the future. Without forward secrecy, an attacker who records encrypted traffic today and steals the server key tomorrow can decrypt all that recorded traffic. With forward secrecy, each session uses unique ephemeral keys — stealing the server key reveals nothing about past sessions.
Static RSA Key Exchange (No Forward Secrecy)
In TLS 1.2, one option was RSA key exchange: the client generates a random pre-master secret, encrypts it with the server's RSA public key, and sends it. The server decrypts it with its private key.
RSA Key Exchange (TLS 1.2 — deprecated):
1. Client generates random pre-master secret
2. Client encrypts it with server's RSA public key
3. Server decrypts with RSA private key
4. Both derive session keys from pre-master secret
Problem: If the server's RSA private key is stolen (even years later),
an attacker who recorded the encrypted traffic can:
1. Decrypt the pre-master secret from step 2
2. Derive the session keys
3. Decrypt ALL recorded past sessions
This is exactly what happened with mass surveillance programs — record everything now, break the key later. RSA key exchange was removed from TLS 1.3 for this reason.
Ephemeral Diffie-Hellman (DHE) — Forward Secrecy
With DHE (Diffie-Hellman Ephemeral), both sides generate fresh DH key pairs for every session and discard them when the session ends:
DHE Key Exchange:
1. Client generates ephemeral DH key pair (a, A = g^a mod p)
2. Server generates ephemeral DH key pair (b, B = g^b mod p)
3. Both compute shared secret = g^(ab) mod p
4. Session keys derived from shared secret
5. After session: a and b are deleted
If server's long-term RSA key is stolen:
- Attacker can impersonate the server (authentication broken)
- But cannot decrypt past sessions (a and b are gone)
- Each past session had unique ephemeral keys that no longer exist
In 2013, Edward Snowden revealed that the NSA was recording encrypted internet traffic at scale. Their strategy: capture the ciphertext now, obtain the private keys later (through legal compulsion, hacking, or mathematical breakthroughs). Any server using RSA key exchange without forward secrecy was retrospectively vulnerable. This revelation accelerated the industry-wide move to ephemeral key exchange. By 2018, all major browsers required forward secrecy.
Part 4: ECDHE — The Modern Standard
ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) is the Diffie-Hellman protocol performed on elliptic curves instead of modular arithmetic. The concept is identical — two parties exchange public values and compute a shared secret — but the math uses elliptic curve point multiplication instead of modular exponentiation.
Why ECDHE Over DHE
| Property | DHE (Finite Field) | ECDHE (Elliptic Curve) |
|---|---|---|
| Key size for 128-bit security | 3072-bit | 256-bit |
| Handshake performance | Slower | 3-10x faster |
| Bandwidth | Larger messages | Smaller messages |
| Forward secrecy | Yes | Yes |
| TLS 1.3 support | Yes (but rare) | Yes (default) |
ECDHE with X25519 is the default key exchange in TLS 1.3 and the most common in TLS 1.2 modern configurations. When you see a cipher suite like TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, the ECDHE part means forward-secret key exchange on an elliptic curve. If you configure an nginx ingress or Envoy sidecar, ECDHE should always be preferred over static RSA key exchange.
X25519 — The Most Popular ECDHE Curve
X25519 (also called Curve25519) is an elliptic curve designed by Daniel Bernstein specifically for Diffie-Hellman key exchange. It has become the dominant choice because:
- Fast: optimized for constant-time implementations (resistant to timing attacks)
- Safe: designed to avoid implementation pitfalls that plague other curves
- Small: 32-byte public keys, 32-byte shared secrets
- Widely deployed: used by Cloudflare, Google, AWS, most modern TLS implementations
# Generate an X25519 key pair with OpenSSL
openssl genpkey -algorithm X25519 -out x25519_private.pem
# Extract the public key
openssl pkey -in x25519_private.pem -pubout -out x25519_public.pem
# View key details
openssl pkey -in x25519_private.pem -text -noout
# X25519 Private-Key:
# priv: (32 bytes)
# pub: (32 bytes)
DHE vs ECDHE Key Exchange
DHE (Finite Field DH)
Classical Diffie-Hellman with modular arithmetic
ECDHE (Elliptic Curve DH)
DH on elliptic curves — smaller and faster
ECDHE in TLS 1.3 — How It Actually Happens
In TLS 1.3, the client sends its ECDHE public key in the very first message (ClientHello). This is what enables the 1-RTT handshake (covered in Module 2):
TLS 1.3 Key Exchange:
ClientHello:
- Supported curves: x25519, secp256r1
- Key share: client's X25519 public key (32 bytes)
ServerHello:
- Chosen curve: x25519
- Key share: server's X25519 public key (32 bytes)
Both sides now compute:
shared_secret = ECDH(my_private_key, their_public_key)
The shared secret is fed into HKDF to derive:
- Client handshake traffic key (AES-256-GCM key)
- Server handshake traffic key (AES-256-GCM key)
- Client application traffic key
- Server application traffic key
In TLS 1.3, ECDHE is not optional — it is the only key exchange mechanism. Every TLS 1.3 connection has forward secrecy by default. The client speculatively sends its key share in the first message, allowing the handshake to complete in a single round trip. This is a major improvement over TLS 1.2, where RSA key exchange (without forward secrecy) was still commonly used.
Part 5: Practical Implications for Kubernetes
Verifying Forward Secrecy
You can check whether a server supports forward secrecy using openssl:
# Connect to a server and check the key exchange
openssl s_client -connect devopsbeast.com:443 2>/dev/null | grep -E "Protocol|Cipher|Server Temp Key"
# Protocol : TLSv1.3
# Cipher : TLS_AES_256_GCM_SHA384
# Server Temp Key: X25519, 253 bits
# "Server Temp Key: X25519" confirms ECDHE key exchange with forward secrecy
# "Temp" means ephemeral — the key was generated for this session only
# Check your nginx ingress controller's TLS configuration
kubectl exec -n ingress-nginx deploy/ingress-nginx-controller -- \
cat /etc/nginx/nginx.conf | grep ssl_prefer_server_ciphers
# ssl_prefer_server_ciphers on;
# Check which protocols are enabled
kubectl exec -n ingress-nginx deploy/ingress-nginx-controller -- \
cat /etc/nginx/nginx.conf | grep ssl_protocols
# ssl_protocols TLSv1.2 TLSv1.3;
If your TLS configuration still allows RSA key exchange (cipher suites without ECDHE or DHE in the name), you do not have forward secrecy. An attacker who records your encrypted traffic today and steals your certificate private key tomorrow can decrypt everything. Ensure your ingress controller, service mesh, and API server only allow ECDHE cipher suites.
Key Exchange in Service Mesh (mTLS)
In Istio or Linkerd, every pod-to-pod connection uses mTLS with ECDHE key exchange. The sidecar proxy (Envoy in Istio, linkerd2-proxy in Linkerd) handles all cryptography:
# Istio: check the TLS version and cipher used between sidecars
istioctl proxy-config secret <pod-name> -o json | jq '.dynamicActiveSecrets'
# Check Envoy's TLS stats
kubectl exec <pod-name> -c istio-proxy -- \
curl -s localhost:15000/stats | grep ssl
# ssl.handshake: 1547
# ssl.versions.TLSv1.3: 1547
# ssl.ciphers.TLS_AES_256_GCM_SHA384: 1547
Service mesh mTLS uses short-lived certificates (Istio default: 24 hours) with automatic rotation. Combined with ECDHE key exchange, this provides defense in depth: even if a certificate is compromised, it expires in hours, and forward secrecy means recorded traffic from before the compromise remains encrypted.
Why RSA Key Exchange Was Removed from TLS 1.3
TLS 1.3 made a bold choice: remove RSA key exchange entirely. This was controversial because RSA key exchange was simpler and widely deployed. But the security benefits were clear:
RSA Key Exchange vs ECDHE (Why TLS 1.3 Chose ECDHE Only)
RSA Key Exchange (Removed)
Client encrypts pre-master secret with server RSA key
ECDHE Key Exchange (Required)
Ephemeral key pair per session, discarded after use
Key Concepts Summary
- Diffie-Hellman key exchange allows two parties to agree on a shared secret over a public channel — the eavesdropper sees all messages but cannot compute the secret
- The security rests on the discrete logarithm problem — computing g^a mod p is easy, but finding a from the result is infeasible for large primes
- Forward secrecy means past sessions stay encrypted even if long-term keys are compromised later — achieved by using fresh ephemeral keys per session
- DHE (Ephemeral DH) provides forward secrecy with finite-field arithmetic — secure but slow with large parameters
- ECDHE provides the same security as DHE with 12x smaller keys and 3-10x better performance — the modern standard
- X25519 is the most popular ECDHE curve — fast, safe, constant-time, used by Cloudflare, Google, and most TLS 1.3 deployments
- TLS 1.3 mandates ECDHE — RSA key exchange was removed entirely because it lacks forward secrecy
- Record-then-decrypt attacks are the practical threat that forward secrecy mitigates — adversaries record encrypted traffic today and attempt to obtain keys later
Common Mistakes
- Allowing RSA key exchange in your TLS configuration alongside ECDHE — clients may negotiate the weaker option
- Confusing DHE with DH — static (non-ephemeral) DH does not provide forward secrecy
- Using small DH parameters (1024-bit) — the Logjam attack showed these are breakable; use 2048-bit minimum
- Assuming forward secrecy is automatic — it requires ephemeral key exchange (ECDHE/DHE), which must be configured and prioritized
- Not verifying key exchange after deployment — use
openssl s_clientto confirm ECDHE is actually being used - Confusing the key exchange algorithm with the authentication algorithm — ECDHE is key exchange, RSA/ECDSA is authentication; they are separate choices in TLS 1.2
What is forward secrecy, and why does TLS 1.3 mandate it?