How SSH achieves forward secrecy

December 4, 2006

A while back a co-worker asked me why SSH (sometimes) uses a second temporary host key in addition to the main host key. I had to think about it for a bit: it's to keep the session private even if the server's host key is later compromised.

(The clever person will notice I could have found this out just by reading the description of the KeyRegenerationInterval sshd parameter. I observe that one rarely pauses to grovel through manpages when discussing half-remembered things with co-workers.)

Public key cryptography is too computationally expensive to do all the time, so SSH sessions are actually encrypted with a random symmetric key; arranging the session key is more or less the only thing done with actual public key cryptography.

(This is common to pretty much every encryption protocol that uses public key cryptography; SSL and even GPG-encrypted email work this way.)

However, if the session key was encrypted with the server's normal host key, there's a problem. An attacker could record a boatload of SSH sessions, then later compromise the server, get its host key, use the host key to decrypt the initial protocol exchange for each session (imitating what the server did during the actual sessions), recover each session key, and decrypted all of those recorded SSH sessions at their leisure.

Preventing this attack is called having perfect forward secrecy.

In version 1 of the SSH protocol, PFS is achieved by using the second, ephemeral set of host keys. The session key is actually encrypted with these ephemeral keys, not directly with the permanent host key, and then the ephemeral keys are discarded every so often. (They could be discarded after every connection, but generating new ones is pretty expensive.)

As the sshd_config manpage mentions in passing, though, this only applies to version 1 of the SSH protocol. So how does SSH v2 achieve (perfect) forward security?

It turns out that the answer is in RFC 4251's section 9.3.7: SSH v2 normally uses Diffie-Hellman key exchange to set up the session keys, which inherently provides perfect forward security without needing a second set of host keys or anything like that. In fact it does it better than SSH v1, because SSH v2 destroys the information that would compromise the session key immediately after generating it, instead of some time later.

(This is one of those entries that I write partly to explain all this to myself, and partly because I had to go digging in RFC 4251 to find the explanation for SSH v2 so I might as well share.)


Comments on this page:

From 192.88.60.254 at 2006-12-05 09:28:34:

Now, since the Diffie-Hellman-Merkle algorithm has been known since the late 1970's, one might ask why the inventors of the SSHv1 protocol didn't use it.

The answer? The algorithm was under patent until 1997. Perfect forward secrecy was sitting there in a known algorithm that no one dared to touch just as the computer industry was beginning to think seriously about encrypted communications over unsecure channels on a large scale.

Had Diffie-Hellman been in the public domain in 1987, the web would likely be a very different place. Secure communication (albeit with unauthenticated endpoints) could have been part of HTTP from the start.

Written on 04 December 2006.
« More fun with Python's indentation rules
A small annoyance with Unix wildcards »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Mon Dec 4 22:01:05 2006
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.