I've seen a lot of 2-party applications that derive a shared key from distinct keys created by each party.

Why is this technique employed? Would it not be better to use those two distinct keys for each party (where both parties know both keys, but each key is used to encrypt and decrypt the messages of the party who created it)?

As an example, I've seen socket servers that use this. Assume 2 servers are running. Both servers send a random 256-bit key, encrypted with the other's RSA public key to each other. This leads to 2 distinct keys that both servers now know. Then both servers XOR these two keys together to derive a common key. Why this is done instead of using both keys in the way I described above?

3 Answers
3

For your example protocol with RSA-exchange in both directions, combining both keys to one protects against some weaknesses:

By combining the random numbers from both sides, the result is really random,
even if one of them has a weak or compromised randomness source.

If one of the private keys is compromised, in your protocol the attacker can
read all the data flowing to its owner. If we combine the random data by XOR
with the other random data to derive the session key, the resulting key is
still unknown to an attacker, and she can't read anything.

Of course, for the actual encryption (and authentication, i.e. a MAC key), you should then use not this combined master secret directly, but derive different keys for the different purposes from it. This avoids some replay attacks.

What kind of replay attacks specifically? I don't see how using the shared key for authentication and encryption would open up a replay vulnerability.
–
Michael J. GrayNov 21 '11 at 1:12

When you use the same key for communication in both directions, a message sent from client to server can be sent back to the client, pretending it came from the server. This can also made impossible by other protocol measures (by including sender/receiver in the authenticated data), but using different keys is an easy way.
–
Paŭlo Ebermann♦Nov 21 '11 at 1:17

Whether using the same key for authentication and encryption is a problem depends on your encryption and authentication algorithms/modes. HMAC combined with AES/CBC seems fine (since they use the key in quite different ways), but I would not use CBC-mode with CMAC with the same key. Either use different keys, or use an authenticated-encryption mode designed to do this with one key.
–
Paŭlo Ebermann♦Nov 21 '11 at 1:20

Generally, these protocols are used to generate symmetric keys from asymmetric keys. You start out with asymmetric keys because that's the only way one party can talk to another party securely without pre-arranging a shared secret. You want to wind up with a symmetric key because only a symmetric key is suitable for bulk or stream encryption.

Assume 2 servers are running. Both servers send a random 256-bit key, encrypted with the other's RSA public key to each other. This leads to 2 distinct keys that both servers now know. Then both servers XOR these two keys together to derive a common key. Why this is done instead of using both keys in the way I described above?

You are assuming there is no attack in progress. Actually, what each side knows is the following:

1) For the key it generated, only it and the intended recipient can know that key. (Because it generated it and encrypted it such that only the intended recipient can decrypt it.)

2) For the key it received, only it and whoever generated that key can know it. (It was encrypted such that only it could decrypt it, but there's no way to know who generated and encrypted it.)

I'm aware of hybrid encryption. In what I am describing, asymmetric encryption is used to deliver 2 symmetric keys to both parties. These 2 symmetric keys are then XORed to produce an effective key that is then used for bulk encryption. I'm wondering why this is done instead of using both keys in the way I described in the question...
–
Chris SmithNov 20 '11 at 15:49

1

@ChrisSmith If you used those keys directly, there would be no security. Each side has no way to know who generated the key it received -- it can only control who has access to the key it generated. If it just started sending data encrypted with the key it received, it would have no way to know who could decrypt that data.
–
David SchwartzNov 20 '11 at 20:34

As David mentioned, symmetric keys are used for stream encryption simply on the basis that symmetric algorithms like Serpent and ChaCha are generally faster than asymmetric algorithms such as RSA relying on large integer arithmetic.

To answer part of your question that I had missed, the reasoning behind using one shared and agreed key versus two distinct keys is to reduce complexity of the system. If you need to keep track of two independent stream states, it's very complex. Not only this but it reduces the amount of data you need to initially share because you are not worrying about initialization vectors or nonces for each separate cipher stream. Finally, another reason to use the singled shared key method from two keys is described in the second paper I referenced and that is for authentication of each party to the other.

For example if I give you an encrypted key to use directly in a cipher and I can get you to encrypt data under that key or know what the contents of the data are as in some protocol negotiations, you become leaky and could make certain weaknesses in an algorithm exploitable which could later be used to analyze some previous stream of data and assist in key recovery or data discovery. You do not know if I am in possession of the key or just the encrypted key. That's what the CAAP protects against.

Actually, using the same stream cipher key (without an or with same initialization vector) for both directions looks like a two-times-pad, definitely not recommendable. And keeping track of two independent stream states seems to be easier than having a common crypto stream state used for communication in both directions. (Though maybe I am misunderstanding you.)
–
Paŭlo Ebermann♦Nov 21 '11 at 1:27