Exchanging data over SSL

I have a basic understanding of public key encryption (by generating a set of public and private keys, I can publish the public key to the world, and anyone who wants to send me an encrypted message can encode their message with my public key. Only I can decode it with my private key).

SSL (eg, over HTTPS) uses this encryption method, meaning when I enter my username and password to access my online banking, any eavesdropper will not be able to “intercept” my username and password.

What I don’t understand is… how does my online bank securely send messages back to me? The bank can’t be encoding their messages with the same public key that I use to encode my messages to them, because then I wouldn’t be able to decrypt the messages.

They encrypt the message sent to you with your public key, you encrypt the message sent to them using their public key. They decrypt your message using their private key, you decrypt their message to you using your private key.

Thanks. Does my web browser create a public/private key pair on the fly?

Essentially yes. There is a two step process, which is typical for most encrypted communication protocols.

The full bore encryption process using pubic key encryption is very computationally expensive. This is a good thing, as if it were not, it would be be intrinsically weakened. So the protocols used generate sessions keys - keys that are only good for the one session. These are exchanged using the public keys, the integrity of which is rooted in the hierarchy of trust of signed certificates. This is why compromising of the certificate signing process is such a big deal.

The encryption used with the session keys is weaker than that afforded for the set-up protocol, but because it is only used for the time of the one session it is much harder to attack - there isn’t enough communicated data to afford many of the attacks possible, and because once the session is done, the keys are never used again, even if the session key was eventually broken, the session is gone, and there is no possibility for a man-in-the-middle attack on the communication.

The generation of session keys needs to be robust - ie as close to pure random as possible. Weaknesses in session key generation are an attack opportunity. The problem being that generating really random numbers is vastly harder than most people imagine. If there is a flaw in the generation mechanism that reduces the range of possible keys (often measured as the entropy of the random number) the communication may become vulnerable to brute forcing of the key from the limited range of keys the system generates. It is very difficult to prove that your random number generator does not suffer from such vulnerabilities.

Long term sessions (such as ssh) will periodically renew the session key to avoid using the weaker key for too long.

Actually the encryption algorithms that are used with the session keys are quite strong. This would normally be AES with 128 or 256 bit keys these days. They’re also very fast.

The public/private key encryption algorithms need much longer keys (like 2048 bits for RSA) to get to the same level of security and are much slower. That’s why public key encryption is used to generate a session key which is subsequently used for the actual encryption of the data exchanged.

The advantage of public key encryption is that you can exchange public keys in the clear while AES and such are symmetric key algorithms where there’s only one key which has to be kept secret.

You don’t need a public/private key at your end to initiate an SSL session towards a server. Your computer can generate a session key and encrypt it with the server’s public key which only the server can decrypt, and then you both have the session key that nobody else knows.

In addition, there’s the Diffie-Hellman key exchange algorithm that allows two parties to come up with a session key even when other people are listening to the exchange.

The problem with all of this is that there can be a “man in the middle”. I.e., Alice and Bob want to exchange encrypted data but Eve pretends to be Bob towards Alice and pretends to be Alice towards Bob. Alice encrypts a message with what she thinks is Bob’s public key, but it’s Eve’s public key so Eve decrypts the message, encrypts it with Bob’s actual public key and sends it on to Bob.

As a result, the “how do I exchange a key with someone far away” problem has been turned into the “how do I know the person far away is who I think it is” problem, which is solved using certificate authorities and public key infrastructures.

Thanks everyone.

This is mostly repeating what has already been said, but the important thing to understand is that data transmitted over TLS is not encrypted with public key encryption. It’s encrypted with ordinary symmetric encryption such as AES. PKE is used only to ensure that both parties have the same session key for the symmetric encryption.

The client generates a random number to use as the symmetric session key. Then it encrypts that key with PKE using the server’s public key and sends it to the server. The server can decrypt it since it has the corresponding private key. After that, the parties can both encrypt data using AES (or whatever symmetric algorithm has been agreed on), and the other one can decrypt that data, but no one else can since no one else has the session key. (Actually it’s a little more complicated, because what’s encrypted and transmitted isn’t actually the session key, but some data that can be used to derive the session key.) There is only one public/private asymmetric key pair used in this process, the one that belongs to the server.

This process also provides authentication – it allows the client to be sure that it’s communicating with the actual intended server and not an imposter, since only the real server has the private key matching the public key. There is an optional “client authentication” mechanism for authentication in the reverse direction, to allow the server to be sure it’s communicating with a known client. In this case the client also has a certificate with a PKE key pair. However this isn’t used very much, since in most real applications the server doesn’t care what client it is communicating with.