8.21 Ensuring Forward Secrecy in a Public Key System

8.21.1 Problem

In a system using public key cryptography, you want to ensure that a compromise of one of the entities in your system won't compromise old communications that took place with different session keys (symmetric keys).

8.21.2 Solution

When using RSA, generate new public keys for each key agreement, ensuring that the new key belongs to the right entity by checking the digital signature using a long-term public key. Alternatively, use Diffie-Hellman, being sure to generate new random numbers each time. Throw away all of the temporary material once key exchange is complete.

8.21.3 Discussion

When discarding key material, be sure to zero it from memory, and use a secure deletion technique if the key may have been swapped to disk (See Recipe 13.2).

Suppose that you have a client and a server that communicate frequently, and they establish connections using a set of fixed RSA keys. Suppose that an attacker has been recording all data between the client and the server since the beginning of time. All of the key exchange messages and data encrypted with symmetric keys have been captured.

Now, suppose that the attacker eventually manages to break into the client and the server, stealing all the private keys in the system. Certainly, future communications are insecure, but what about communications before the break-in? In this scenario, the attacker would be able to decrypt all of the data ever sent by either party because all of the old messages used in key exchange can be decrypted with all of the public keys in the system.

The easiest way to fix this problem is to use static (long-term) key pairs for establishing identity (i.e., digital signatures), but use randomly generated, one-time-use key pairs for performing key exchange. This procedure is called ephemeral keying (and in the context of keying Diffie-Hellman it's called ephemeral Diffie-Hellman, which we discussed in Recipe 8.17). It doesn't have a negative impact on security because you can still establish identities by checking signatures that are generated by the static signing key. The upside is that as long as you throw away the temporary key pairs after use, the attacker won't be able to decrypt old key exchange messages, and thus all data for connections that completed before the compromise will be secure from the attacker.

The only reason not to use ephemeral keying with RSA is that key generation can be expensive.

The standard way of using Diffie-Hellman key exchange provides forward secrecy. With that protocol, the client and server both pick secret random numbers for each connection, and they send a public value derived from their secrets. The public values, intended for one-time use, are akin to public keys. Indeed, it is possible to reuse secrets in Diffie-Hellman, thus creating a permanent key pair. However, there is significant risk if this is done naïvely (see Recipe 8.17).

When using RSA, if you're doing one-way key transport, the client need not have a public key. Here's a protocol:

  1. The client contacts the server, requesting a one-time public key.

  2. The server generates a new RSA key pair and signs the public key with its long-term key. The server then sends the public key and the signature. If necessary, the server also sends the client its certificate for its long-term key.

  3. The client validates the server's certificate, if appropriate.

  4. The client checks the server's signature on the one-time public key to make sure it is valid.

  5. The client chooses a random secret (the session key) and encrypts it using the one-time public key.

  6. The encrypted secret is sent to the server.

  7. The parties attempt to communicate using the session key.

  8. The server securely erases the one-time private key.

  9. When communication is complete, both parties securely erase the session key.

In two-way authentication, both parties generate one-time keys and sign them with their long-term private key.

8.21.4 See Also

Recipe 8.17, Recipe 13.2