Diffie-Hellman Key Exchange¶
How two parties agree on a shared secret over a channel everyone can listen to — the idea that started public-key cryptography.
What it is¶
Published in 1976 by Whitfield Diffie and Martin Hellman, this was the first method letting two people who have never met derive a shared secret in the open, with an eavesdropper unable to recover it. That shared secret then keys a fast symmetric cipher like AES. Its security rests on the discrete logarithm problem.
The classic version below works over integers mod a prime. The modern, faster version is the elliptic-curve form — see X25519, which has largely replaced it.
How it works¶
Both sides agree on public parameters: a large prime p and a generator g.
- Alice picks secret
a, sendsA = gᵃ mod p. Bob picks secretb, sendsB = g^b mod p. - Alice computes
Bᵃ mod p, Bob computesA^b mod p. - Both equal
g^(ab) mod p— the shared secret.
An eavesdropper sees p, g, A, B but can't get g^(ab) without solving the
discrete log to recover a or b.
When to use it¶
- Establishing a session key before symmetric encryption — this is what the handshake in TLS, SSH, and VPNs does.
- Use ephemeral keys (DHE/ECDHE) for forward secrecy — a fresh key pair per session means a later key compromise can't decrypt past traffic.
- Prefer X25519 for new systems: smaller, faster, harder to
misuse than classic mod-
pDH.
Example (Python)¶
from secrets import randbelow
# RFC 3526 group 14: a 2048-bit safe prime
p = int("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"
"4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"
"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
g = 2
a = randbelow(p - 3) + 2 # Alice's secret
b = randbelow(p - 3) + 2 # Bob's secret
A, B = pow(g, a, p), pow(g, b, p) # sent in the open
print(pow(B, a, p) == pow(A, b, p)) # True: both now hold g^(ab) mod p
# run the shared secret through HKDF before using it as a key
Security notes¶
- Plain DH has no authentication — it's wide open to a man-in-the-middle who swaps the public values. Combine it with a signature (Ed25519) or certificate.
- Derive, don't use raw. Feed
g^(ab)through a KDF (HKDF) before it becomes a cipher key. - Use ephemeral keys for forward secrecy; use ≥2048-bit
pfor classic DH. - Quantum computers break the discrete log — see ML-KEM.
See also¶
- X25519 — the modern elliptic-curve version
- HKDF — turning the shared secret into keys
- AES / ChaCha20-Poly1305 — what the key feeds
References¶
- Diffie, W.; Hellman, M. (1976). "New Directions in Cryptography"
- RFC 7748: Elliptic Curves for Security (X25519)