![]() | ![]() |
Just as many people buy expensive and secure safes and use them badly, many people take good encryption algorithms and build them into insecure systems.
In order for a client and a server to have an authenticated and secure private communication session, the following are needed:
Even when this kind of negotiation isn't needed, most protocols support negotiation in order to allow future implementations to change the encryption algorithm that is used. New encryption algorithms are frequently discovered, and so are new problems with old encryption algorithms. You don't want to be stuck using an encryption algorithm that somebody has figured out how to decrypt easily, or an algorithm that's half the speed of the newest and best thing. Once again, you need to be able to negotiate.
Safe negotiation is difficult. It should be possible for each end of the connection to specify what algorithms are acceptable. If one end can convince the other to negotiate little or no security, a hostile client or server can force connections that will leak information. Even more importantly, it should not be possible for any third party to influence the negotiation. You do not want an attacker to be able to select the encryption that's easiest to break!
A secure protocol uses a negotiation that:
Uses message integrity protections to prevent third-party tampering (see the earlier discussion for more information on message integrity)
A secure protocol therefore provides for mutual authentication; the server authenticates itself to the client, and the client authenticates itself to the server. There are various ways of doing this, most of them based on the same trick where each side proves that it can decrypt a value with a secret that only the authentic participant could know. This secret could be a key used with a symmetric algorithm, or it could be the private half of a public key/private key pair; it makes a difference in configuring the servers and clients but doesn't change the basis for the authentication. In either case, each side sends the other an unpredictable value and gets it back in a form that proves the other side could decrypt it.
Perfection is normally difficult or expensive to obtain, and perfect forward secrecy is no exception. In general, temporary keys are generated using information that is available to one or both sides of the transaction, and there are also usually situations where one side or the other is not sure whether or not the transaction has completed, and needs to keep the key around until the situation is clarified. For practical reasons, most systems implement partial perfect forward secrecy, where there is some period of time during which it is possible to recreate the shared secret. After this time period, things are reset, and the secret is destroyed.