Suppose that I have $n$ secure 32-bit keys that were generated separately using methods that are known to be secure. For example, one of them might have been generated by using a proven CSPRNG. Another may have been generated using PBKDF2.
Now, I want to turn all of these keys, combined together in to a new key that I can use to encrypt and decrypt data.
The important thing is that I want to require all of the keys to be present in order to perform the encryption and decryption.
What I want to know is, what is the best way to combine these keys and maintain the highest level of security against attacks?
For example, I could just concatenate all the 32-bit keys and then run them through PBKDF2 again:
# pbkdf2(key, salt, iterations, derived_key_length)
# Also, "a + b" indicates concatenating a + b as strings, i.e. "hello" + " world" = "hello world"
new_key = pbkdf2(key1 + key2 + key3, some_salt, 10000, 32)
Or, instead of concatenating them, I could concatenate some of them in the salt:
new_key = pbkdf2(key1, key2 + key3, 10000, 32)
Or, I could iteratively run pbkdf2:
temp_key = pbkdf2(key1, key2, 10000, 32)
new_key = pbkdf2(key3, temp_key, 10000, 32)
Or, I could concatenate them all and hash them:
new_key = sha1(key1 + key2 + key3)
Or, I could iteratively hash them with concatenated versions of the previous hash:
a = sha1(key1)
b = sha1(a + key2)
new_key = sha1(b + key3)
Or, I could produce a hash using one of the above methods and then run that hash through PBKDF2:
hash = sha1(key1 + key2 + key3)
new_key = pbkdf2(hash, some_salt, 10000, 32)
Or, I could xor them all together:
new_key = xor(xor(key1, key2), key3)
Or, xor them all together, and then run though pbkdf2, etc. etc.
Clearly there are a ton of ways to combine these keys to produce a new secure key.
Is there any prior work on this? What is the best and most secure way to do this?
If any of the above methods are not secure, can you explain why?
P.S. As an additional aspect of this question, I am curious if the "password" or the "salt" are more or less secure places to put entropy. For example, are both of the following equally secure?
new_key = pbkdf2(key1 + key2, key3, 10000, 32)
and
new_key = pbkdf2(key1, key2 + key3, 10000, 32)