Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol
updated by
- rfc-8270 — Increase the Secure Shell Minimum Recommended Diffie-Hellman Modulus Size to 2048 Bits
Extracted elements (22)
Both client and server may reduce the size of their private exponents to speed up key exchange. The private exponent should be at least twice as long as the key material generated from the shared secret (per van Oorschot and Wiener). Safe primes make short exponents safe from discrete-log attacks.
Fixed DH groups (as used in diffie-hellman-group1-sha1) create a long-term security risk because extensive precomputation and improved discrete logarithm algorithms could compromise a fixed group over the lifetime of the SSH protocol. Dynamic group negotiation reduces the incentive for precomputation by allowing the server to rotate groups over time.
Generator value 2 is recommended because it improves multiplication efficiency. It is usable even when not a primitive root, as it still covers half of the space of possible residues. The modulus sieve can be limited to primes where p mod 24 = 11 to ensure 2 is a valid generator.
SSH_MSG_KEX_DH_GEX_REQUEST_OLD (message 30) exists for backward compatibility: the client sends only 'n' instead of 'min || n || max', and the exchange hash H is computed using only 'n' rather than the full triple. Implementations must handle both variants.
Either side MUST NOT send or accept e or f values that are not in the range [1, p-1]. If this condition is violated, the key exchange fails. This prevents confinement attacks.
Servers and clients SHOULD support groups with a modulus length of k bits where 1024 <= k <= 8192. The recommended values for min and max are 1024 and 8192 respectively.
The hash algorithm used in key exchange (e.g., SHA-256 for diffie-hellman-group-exchange-sha256) must also be used in the key derivation pseudo-random function (PRF), as required by RFC 4253's 'Output from Key Exchange' section.
The server should return the smallest group it knows that is larger than the client-requested size. If no larger group exists, the server SHOULD return the largest group it knows, and in all cases the returned group SHOULD be at least 1024 bits.
To prevent confinement attacks, both sides MUST accept the shared secret K only if 1 < K < p - 1.
Message numbers defined: SSH_MSG_KEX_DH_GEX_REQUEST_OLD=30, SSH_MSG_KEX_DH_GEX_GROUP=31, SSH_MSG_KEX_DH_GEX_INIT=32, SSH_MSG_KEX_DH_GEX_REPLY=33, SSH_MSG_KEX_DH_GEX_REQUEST=34. Numbers 30-49 are key-exchange-specific and may be redefined by other kex methods.
The method 'diffie-hellman-group-exchange-sha1' specifies Diffie-Hellman Group and Key Exchange using SHA-1 as the HASH function for computing the exchange hash.
The method 'diffie-hellman-group-exchange-sha256' specifies Diffie-Hellman Group and Key Exchange using SHA-256 as the HASH function. SHA-256 must also be used in the key derivation PRF per RFC 4253.
The server maintains a list of safe primes and corresponding generators. A prime p is safe if p = 2q + 1 and q is also prime. The generator g must be chosen so the order of the generated subgroup does not factor into small primes (order must be q or p-1).
Only safe primes (p = 2q + 1, q prime) must be used as moduli, because they allow selection of a generator whose subgroup order does not factor into small primes, preventing subgroup confinement attacks. Van Oorschot and Wiener show that short private exponents are safe specifically with safe primes.
The least significant bit of the private exponent can be recovered when the modulus is a safe prime (Menezes et al.). This is not a practical concern if the private exponent is sufficiently large; Waldvogel and Massey show that random exponents chosen from {0,...,p-2} have key entropy less than 2 bits below the maximum.
Using multiple moduli inhibits a determined attacker from precalculating moduli exchange values and discourages dedication of resources for analysis of any particular modulus, thereby mitigating precomputation-based attacks against the DLP.
The group exchange proceeds in five steps: (1) client sends min/n/max size request; (2) server responds with chosen group (p, g); (3) client sends e = g^x mod p; (4) server computes K, H, signs H, and sends K_S || f || signature; (5) client verifies host key, computes K and H, and verifies the signature.
SSH_MSG_KEX_DH_GEX_GROUP is sent by the server and contains: byte (message type 31), mpint p (safe prime), mpint g (generator for subgroup in GF(p)).
SSH_MSG_KEX_DH_GEX_INIT is sent by the client and contains: byte (message type 32), mpint e (client's DH public value, e = g^x mod p).
SSH_MSG_KEX_DH_GEX_REPLY is sent by the server and contains: byte (message type 33), string K_S (server public host key and certificates), mpint f (server's DH public value), string s (signature of exchange hash H).
SSH_MSG_KEX_DH_GEX_REQUEST is sent by the client and contains: byte (message type 34), uint32 min (minimum acceptable group size in bits), uint32 n (preferred group size in bits), uint32 max (maximum acceptable group size in bits).
The exchange hash H is the HASH of the concatenation of: string V_C, string V_S, string I_C, string I_S, string K_S, uint32 min, uint32 n, uint32 max, mpint p, mpint g, mpint e, mpint f, mpint K. This binds all negotiation parameters into the session hash.