# AES encryption with multiple keys

I would like to encrypt some data using a combination of multiple keys. There would be two keys: a client keys that would be generated for each client and a single server/application key used by everyone. The idea is to be able to encrypt/decrypt the data only if we are in possession of both keys. So neither the server nor the client could decrypt the data alone.

I know that I could simply encrypt the data using the client key and then encrypt the data using the server keys, but I was wondering if it was possible to just combine the keys in order to create the common decryption key as I am not fond of multiple encryption... I have looked into Secret Sharing, but from what I experimented with the crypto++ library, I can only generate n keys from a message (the message would be the merged key in my case). I would rather want to generate a client key, then merge this client key with a fixed server key to generate the final key used for encryption.

Is XORing the keys together a good solution ? (I believe if both of them have the same character at the same location, it would reduce the encryption strength of the final key...)

Also, can I only use a single IV for both keys in this context ? The IV would of course be randomly generated for every client.

-

## 1 Answer

You asked several questions above. I will address one in specific that stands out to me, and that is your question about XORing the keys together. Your statement that they might both have the same character at the same location that would yield a null byte is disconcerting: passwords are not normally used directly as encryption keys.

Mathematically, a string of eight zero bits is not going to reduce the strength of AES, as AES does not have any known weak keys. However, if an attacker knows you will be using ASCII characters directly as key material, his job of attacking just got that much easier, because he understands the limits imposed by such a restriction.

If you use ASCII characters as your key, you would need to tell your clients they must use exactly a 16 character password, which will limit their creativity (greatly reducing the pool of likely passwords they might choose.) ASCII severely constrains the number of bits that can change in a given byte: there are few people who could enter a character on a keyboard that is outside the range of the common letters, numbers, and symbols. By limiting key bytes to exclude values in the ranges of 0x00-0x1F and 0x80-0xFF, you've artificially limited your keys to $96^{16}$ instead of $256^{16}$. This dangerously weakens your implementation.

Consider using a key derivation function to transform the passwords into the cryptographic key. Such an algorithm combines all the bits of input and produces a key of the desired length. By using a key derivation function you could require a 64 character minimum password, and combine all that material to produce a much stronger key - $96^{64}$ is significantly stronger than $96^{16}$.

-
Basically I'll have 2 randomly generated key, one that is fixed and one that change for every client. I will generate two 64 characters long keys. Do you recommend any derivation algorithm to generate the final key ? I was talking about XORing the keys as an example, but it could be hashing the concatenation of both keys, etc... –  adaigle May 29 '13 at 13:54
Most KDFs are used to store hashes of passwords in databases, making them resistant to rainbow table attacks. They make execution take a huge amount of CPU, and may be overkill for your application. If that's not an issue for you, taking the first 128 bits from an ordinary secure hash algorithm like SHA-2 would enable you to concentrate all the available entropy from the password into the key bits. And your original suggestion of XOR should be a fine choice for mixing two such generated keys, as would concatenating the passwords prior to hashing. –  John Deters May 29 '13 at 14:25