I want to combine two or more keys to create a single encryption key that relies on all of them. What is the proper method for doing that? Simple XOR? Using hash functions? Something else?

I personally used this: k = md5( key1 || key2 ). Note: || means concatenation. I used md5 because I use 128-bit encryption and thus need a 128 bit output key.

Some other questions arise here for me:

  1. Is using MD5 secure for this specific purpose?

  2. I don't know of any other standard 128-bit output hash functions. It seems newer cryptographic hash functions all have 256-bit and more output lengths. So is using another hash function that has a 256/512-bit output and then truncating the result down to 128 bits secure to an equal or more degree than using MD5?

Note that key1 and key2 are random keys, not passwords, and thus key stretching is not relevant or applicable.

If it is relevant, I generated both keys, and I know that both keys are cryptographically random. Neither key was supplied by an untrusted party. At present both keys happen to be the same length, but I'd prefer a more general solution that does not rely upon this assumption, if possible.

  • $\begingroup$ Do the input keys have known constant length? $\endgroup$ May 2, 2012 at 18:12
  • 1
    $\begingroup$ I would not use md5 for anything to be honest. There are better ways to generate a key. $\endgroup$
    – Ramhound
    May 2, 2012 at 18:50
  • 5
    $\begingroup$ There are no known MD5 weaknesses that have any practical bearing on the strength of this scheme. Still, I'd use something else just so that you don't have to keep explaining that. $\endgroup$ May 2, 2012 at 19:29
  • $\begingroup$ @CodeInChaos: currently yes, but maybe not in the future. And generally, it is obvious that a generic/flexible method is much much better. $\endgroup$
    – H M
    May 2, 2012 at 19:29
  • 1
    $\begingroup$ Are both keys chosen by you, or can one be chosen by an untrusted party? Are key1 and key2 of sufficient length to avoid one being brute forced if the other is known? $\endgroup$
    – MZB
    May 3, 2012 at 23:33

4 Answers 4


If the keys have constant, known length, I'd concatenate them, and then apply SHA256. If they have variable length, applying some separation mechanism might be useful.

Truncating hash functions works well. If the original hash function is good, a truncated hash function has the same properties, albeit at a correspondingly lower security level. Truncating SHA-256 is certainly better than using MD5.

I recommend something like:

Truncate(SHA-256(output-size || number-of-keys || sizeof(key1) || key1 || sizeof(key2) || key2 ...), output-size) where output-size <= 256

  • $\begingroup$ what do u mean from 'applying some separation mechanism'? why? $\endgroup$
    – H M
    May 2, 2012 at 19:39
  • 1
    $\begingroup$ It's probably unnecessary, at least I can't think of an attack that exploits it, but feels like proper hygiene. $\endgroup$ May 2, 2012 at 19:41
  • $\begingroup$ Alternatively, you could also use any standard key derivation function, such as HKDF (RFC 5869). $\endgroup$ Jan 11, 2013 at 2:06

If I understand your question correctly, you have $n$ keys: $K_0$ ... $K_{n-1}$ and you want to derive a key, $M$ such that:

  • $M$ is 128 bits (16 bytes) in size.
  • $M$ is derived using a deterministic algorithm.
  • $M$ cannot be derived without the knowledge of every $K$.

If every $K$ is 128 bits in size:

$M = K_0 \oplus K_1$ ... $\oplus K_{n-1}$

If every $K$ is smaller than 256 bits in size:

$K_x = K_x || [0x00 * (32 - length(K_x))]$

$K_x = H_{SHA-256d}(K_x)$

$K_x = truncate(K_x, 16)$

$M = K_0 \oplus K_1$ ... $\oplus K_{n-1}$

If every $K$ is larger than 256 bits in size:

$K_x = H_{SHA-256d}(K_x)$

$K_x = truncate(K_x, 16)$

$M = K_0 \oplus K_1$ ... $\oplus K_{n-1}$

  • 2
    $\begingroup$ why do u pad k if it is smaller than 256 bits? $\endgroup$
    – H M
    May 5, 2012 at 4:33
  • $\begingroup$ While xor would work in this particular case, it is less robust -- e.g., it becomes vulnerable if any of the keys are supplied by an untrusted party. Therefore, I prefer the @CodesInChaos's method of hashing the concatenation of the keys. $\endgroup$
    – D.W.
    Jan 10, 2013 at 2:29

If you have a cryptographic key (K), you can split it into any number of parts (P) using an XOR.

Px = P1 XOR P2 XOR P3 XOR ... XOR Px-1 XOR K

Then destroy the key K, and distribute all parts P.

To retrieve K, just XOR P1 to Px, the result will be the original key K.




  • $\begingroup$ i don't want to split a key into several parts. i want to combine several independent keys into one. it is not secret sharing. $\endgroup$
    – H M
    May 2, 2012 at 19:31
  • $\begingroup$ @H M: replace 'parts' with 'subkeys'. combining several subkeys (parts) into the one final key is exactly what you are doing right now. Petey B proposes to (sk1 ^ sk2 ^ sk3) instead of concatening the (sub)keys and then md5 the result ... $\endgroup$
    – akira
    May 4, 2012 at 5:53

the problem with hash-functions such as md5 and sha* are that they were not designed to solve the problem you have: create a cryptographic hard key for further use. they were design to calculate hashes very very fast without having a too high chance of hash-collisions.

what you really want to use is a so called key derivation function. examples for such functions are:

what kind of secrets you pipe into that function to get the actual key is pretty much up to you. the main point of such functions is that it takes relatively long time to calculate the key and thus slowing down brute force attacks quite a bit.

  • 3
    $\begingroup$ "Note that key1 and key2 are random keys, not passwords, and thus key stretching is not a relevant and applicable thing." $\endgroup$ May 3, 2012 at 9:44
  • $\begingroup$ @CodeInChaos: the keystretching part is not the point of using a better kdf than "md5" ... $\endgroup$
    – akira
    May 3, 2012 at 9:48
  • 1
    $\begingroup$ keystreching is pretty much the only point of using slow KDFs over cheap hashes such as SHA-2. If the input has sufficient entropy, the slow down isn't necessary, since guessing the input is already infeasible. $\endgroup$ May 3, 2012 at 9:50
  • $\begingroup$ @CodeInChaos: no. $\endgroup$
    – akira
    May 3, 2012 at 9:51
  • 1
    $\begingroup$ @akira: What is the process for what you mean by "brute-forcing md5(key1||key2) or sha2(key1||key2)"? $\endgroup$
    – user991
    May 3, 2012 at 11:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.