The use case is analogous to accessing a safe box in a bank. There is a per-user key, unique for each user, either generated by the system or hashed from the user's password. And there is a system-wide, master key for all the users. Both keys are required to be able to decrypt data. What's the best way to implement it?

  1. Multiple encryption. It seems I can follow the recommendation on the Wiki page and use the method described by Bruce Schneier.

  2. Encrypt the per-user key with the master key. Use the encrypted key to encrypt and decrypt.

  3. Concatenate the per-user key with the master key. User the concatenated key to encrypt and decrypt.

Especially 2 and 3 would be simpler than 1. But are they free of flaws? I couldn't find examples of them.

  • 2
    4) Use key1 XOR key2. You might aso want to feed the combined keys into a KDF to derive the final key.
    – rossum
    Oct 26 '14 at 19:48
  • Research key splitting.
    – MCW
    Oct 31 '14 at 11:22

The important point is to work out who should handle the keys. Without multiple encryption, then there must be, upon encryption and decryption, a system that at least transiently learns all the keys. For instance, if the "master key" and "user key" are concatenated (your "method 3"), then both keys are present simultaneously in the RAM of the computer that uses the concatenation to encrypt or decrypt.

If that is not a problem, then the general case is Shamir's Secret Sharing: the secret value (the actual encryption key) is split into n shares, such that any t shares are sufficient to rebuild the secret, but t-1 shares yield no information whatsoever. In your situation, n = t = 2; the sharing algorithm is then mostly a XOR of the two shares (the user key and the master key), which corresponds to what @rossum suggested as a comment.

On the other hand, if you want to avoid having any system learning both keys at any time, then you will need to use multiple encryption. If the data is encrypted by the user first, then by the bank, then decryption will be done in reverse order; the user will not learn the bank key, the bank will not learn the user key, and the bank will not learn the cleartext data either.


None of the above. You should create a message key per entry, and encrypt that message key with the user key and the back-office key. Then use the message key to encrypt/decrypt the data of the user. In this way the keys can remain independent and you can use either to encrypt/decrypt. You may want to consider using an asymmetric public/private key pair for the user and/or the back-office keys.

So you would store:

E(K_b, K_d) | E(K_u, K_d) | E(K_m, M)

where E is encryption, the first argument is the key, K_m is the backoffice key (or, K_u is the user key and K_m is the random key generated to encrypt the message.

Always store some protocol identifier (e.g. initial byte) as well so you can update your protocol later on.

  • Oops, answered this before seeing it is off topic here. I should stop switching between crypto, security and SO all the time :) Oct 26 '14 at 20:00
  • thanks for the answer. Can you be more specific? How exactly to encrypt the data key with the user key and the master key, by chaining the encryption?
    – neurite
    Oct 27 '14 at 18:22
  • Just separately would work fine. Then store the results together with the encrypted data. Oct 27 '14 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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