RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol
updated by
- rfc-9142 — Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH)
Extracted elements (24)
RSA key exchange was chosen over Diffie-Hellman because it uses an order of magnitude less CPU time on the client, making it particularly suitable for slow client systems such as mobile devices.
The client generates K in the range 0 <= K < 2^(KLEN-2*HLEN-49) to ensure K's mpint encoding is always short enough to be encrypted under K_T using RSAES-OAEP, as proven in Appendix A where maximum message length equals (KLEN-2*HLEN-9)/8 bytes.
The encoding of the encrypted secret in SSH_MSG_KEXRSA_SECRET uses I2OSP (from RFC 3447) combined with SSH string encoding, which is similar but not identical to SSH mpint encoding; this matches the encoding used by ssh-rsa signatures in RFC 4253.
If a decryption error occurs when the server decrypts K, the server SHOULD send SSH_MESSAGE_DISCONNECT with reason code SSH_DISCONNECT_KEY_EXCHANGE_FAILED and MUST disconnect.
The exchange hash H SHOULD be kept secret, as it is used to authenticate the key exchange.
The modulus of the transient RSA key K_T MUST be at least MINKLEN bits long.
The signature algorithm MUST be applied over H, not the original data; where a signature algorithm includes its own hashing, the data is first hashed with HASH to compute H, and H is then hashed again as part of the signing operation.
Each RSA key exchange method is parameterized by HASH (the hash algorithm), HLEN (output length of HASH in bits), and MINKLEN (minimum transient RSA modulus length in bits).
Encryption of the shared secret K uses RSAES-OAEP as specified in RFC 3447, with MGF1-with-HASH as the mask generation function, HASH as the hash, and an empty label.
Message numbers assigned: SSH_MSG_KEXRSA_PUBKEY=30, SSH_MSG_KEXRSA_SECRET=31, SSH_MSG_KEXRSA_DONE=32.
The exchange hash H is computed as HASH of the concatenation of: V_C, V_S, I_C, I_S (kexinit payloads), K_S (host key), K_T (transient RSA key), RSAES_OAEP_ENCRYPT(K_T, K) (encrypted secret), and K (shared secret as mpint).
The RSA key exchange consists of three messages: SSH_MSG_KEXRSA_PUBKEY (server sends transient RSA public key K_T), SSH_MSG_KEXRSA_SECRET (client sends RSAES-OAEP encrypted shared secret K), and SSH_MSG_KEXRSA_DONE (server sends signature of exchange hash H).
The rsa1024-sha1 method uses SHA-1 (HLEN=160) and requires a minimum transient RSA modulus of 1024 bits (MINKLEN=1024).
The rsa2048-sha256 method uses SHA-256 (HLEN=256) and requires a minimum transient RSA modulus of 2048 bits (MINKLEN=2048).
IANA assigned the names 'rsa1024-sha1' and 'rsa2048-sha256' as Key Exchange Method Names in the SSH protocol assigned numbers registry in accordance with RFC 4250.
If the server's transient RSA private key is revealed, the session key is revealed; servers SHOULD use each RSA key for as few key exchanges as possible and erase the private key from memory as soon as it is no longer required.
K_T SHOULD NOT be used as a host key or server key in other protocols; RFC 3447 recommends that RSA keys used with RSAES-OAEP not be used with other schemes or with RSAES-OAEP using a different hash function.
SHA-1 is appropriate for applications requiring up to 80 bits of security; SHA-256 is appropriate for those requiring up to 128 bits of security, consistent with RFC 3447's recommendation that hash output length be twice the required security level.
The client MUST use a high-quality cryptographic pseudo-random number generator to generate K; using a bad random number generator will allow an attacker to break all encryption and integrity protection of the SSH transport layer.
The method is designed to resist collision attacks on the exchange hash: the server commits its input before seeing K, and the one-way nature of RSA encryption prevents the client from choosing K to cause a hash collision.
Unlike Diffie-Hellman, this method allows the client to fully determine the shared secret K; protocol extensions that use K directly and assume it was generated by Diffie-Hellman should be viewed with extreme suspicion.
SSH_MSG_KEXRSA_DONE carries a byte message type (32) and a string containing the server's signature of exchange hash H with its host key.
SSH_MSG_KEXRSA_PUBKEY carries a byte message type (30), a string for server public host key and certificates (K_S), and a string for the transient RSA public key (K_T) encoded per the ssh-rsa scheme.
SSH_MSG_KEXRSA_SECRET carries a byte message type (31) and a string containing RSAES-OAEP-ENCRYPT(K_T, K), the encrypted shared secret; the encoding uses I2OSP to produce an octet string similar but not identical to SSH mpint encoding.