Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I use AES encryption on a website. At the moment, the key is stored in the source of the PHP script that does the encryption/decryption process thanks to openssl. I know that it isn't secure, so I want to put parts of the key in different places:

  • first part in PHP source
  • second part as server environment variable
  • third part as htaccess env var
  • other places in case I remind them

I know that this proceeding doesn't add, at the end, to security, but it makes the cracking a little more difficult (considering that I can't use hardware devices), because the blackhat needs to get all the parts, not only the source of a script.

The question is about the safest way to do it.

  • splitting password in 3 parts, putting them in the different places mentioned and join the pieces when I need the complete key
  • combining them in other ways, like:

Example

What do you think about it? Thanks a lot for your useful help

share|improve this question
    
Encryption of what, exactly? If it's user data, why not derive the key from the user's password? –  Polynomial Nov 15 '12 at 13:08
    
@Polynomial the admin needs to read user data. So, if the key is derived from the user pass, then the admin has to know the user pass, not exactly a good idea. –  Surfer on the fall Nov 15 '12 at 13:24
    
That's not necessary. Just create an independent key for encrypting the data, then xor that key with the user key and an admin key (generated via the passwords and independent salts). –  Polynomial Nov 15 '12 at 13:29
    
@Polynomial I'm sorry, I don't understand what you've written. Could you expand your comment? Thanks a lot –  Surfer on the fall Nov 15 '12 at 13:34
    
I'll write an answer. –  Polynomial Nov 15 '12 at 13:34

3 Answers 3

up vote 6 down vote accepted

Essentially what you're attempting to do is backdoor each user's account in a way that allows only the user and a single administrative user to access their data. This can be achieved as follows:

us  = User salt  = Random unique value (not the same salt as used for authentication)
as  = Admin salt = Random unique value (not the same salt as used for authentication)

uk  = User key    = pbkdf2(user_pass, salt1, 256, rounds)
dk  = Data key    = random 256-bit key
ak  = Admin key   = pbkdf2(admin_pass, salt2, 256, rounds)
P   = RSA private key
p   = RSA public key

uk' = Encrypted user key    = dk ^ uk
dk' = Encrypted data key    = RSA_Encrypt(dk, p)
P'  = Encrypted private key = AES_Encrypt(P, ak)

m = message
iv = initialisation vector (random unique value)
c = ciphertext = AES_Encrypt(m, iv, dk)

We then store uk', dk' and iv with the data record we're encrypting. We store us with the user account record. We also store P' and as with our admin account record. The public key P can be stored in the code.

The user decryption works as follows:

  1. Compute uk from the user password and us.
  2. Xor uk' with uk to retrieve dk.
  3. Decrypt c using iv and dk, giving us m.

The admin decryption works as follows:

  1. Compute ak from the admin password and as.
  2. Decrypt P using AES_Decrypt(P', ak)
  3. Decrypt dk using RSA_Decrypt(dk', P)
  4. Decrypt c using iv and dk, giving us m.

Note that when I say "encrypt" and "decrypt" in reference to RSA, it's not really encryption, but it is more or less semantically equal.

share|improve this answer
    
Thanks a lot. I'm trying to understand your message. But where should I store user salt? Is us a random value generated during sign up or every data insertion? –  Surfer on the fall Nov 15 '12 at 14:23
    
During sign-up. It must be random and unique, and independent of the salt used for the authentication hash. –  Polynomial Nov 15 '12 at 14:24
2  
@Surferonthefall There is no known plaintext attack here. You need to know the password to compute uk. And yes, xor is fine, since the two values are of equal length. An xor provides absolutely ideal security in that case - it works on the same principle as one-time-pad. –  Polynomial Nov 15 '12 at 14:51
1  
@Surferonthefall You shouldn't store the plain password at all, but you should store the user key uk. There are a few ways to do it with reasonable safety. One is to use something like APC or memcached to store the value in memory. The other is to put the value in the session, and configure your sessions to write to a ramfs partition, so they're only ever in memory. –  Polynomial Nov 15 '12 at 21:54
1  
@Surferonthefall No, it need not be unique. The IV takes care of the uniqueness requirement. Make sure you're using CBC mode for AES though. –  Polynomial Nov 26 '12 at 10:44

If I understood correctly, you're looking for the concept of secret sharing.

Quoting Wikipedia article:

Secret sharing (also called secret splitting) refers to methods for distributing a secret amongst a group of participants, each of whom is allocated a share of the secret. The secret can be reconstructed only when a sufficient number, of possibly different types, of shares are combined together; individual shares are of no use on their own.

If you're looking for some more concrete examples, look for Shamir's scheme, Blakley's scheme.

Unfortunately I cannot recommend any ready to use libraries, but that does not mean such do not exist!

share|improve this answer
1  
Please consider improving your answer by quoting parts of the article. –  Simon Sep 24 '13 at 12:54
2  
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. –  Xander Sep 24 '13 at 13:43
    
good points, thank you for the feedback, I'll do that –  Cyryl Płotnicki-Chudyk Sep 26 '13 at 8:43

To put what Polynomial is saying another way, if you are trying to make it so that encryption works for user data so that only the user and administrators can get to it, the critical piece is to not store the ability to get the information on the server. For users, this is done via their password, for administrators, it is done through their private key (which can also be tied to a password.)

For each user account, you make a new symmetric key. You store that key encrypted based on the users' password so that only the user can get at that version. You then also store the same key but encrypt it using the public key of the administrator, this ensures that the second copy of the user key can only be accessed by the holder of the administrator private key. If the user's password needs to be administratively changed, the administrator can then decrypt the user key with their private key and re-encrypt it based on the user's new password.

Ultimately, the primary limitation is that the administrative user still has to provide the private key to do anything, so I'm not sure if this fits your use case or not. If you need the system to be able to reset a user's password automatically, then you have to have a way to get at the encryption key to re-encrypt it with the new user password.

While you are correct that it doesn't add much security, I would say that your best bet for defense in depth via multiple storage locations (if you don't have any better option) is to use multiple nested encryptions with different keys. ie, store a full, different symmetric key at every location, and require each key to be used in sequence for the data key decryption and rotate them regularly. I must emphasize that this adds a minimal amount of protection, but it does at least make the best of a bad situation if you must have the ability to automatically access the protected data.

share|improve this answer
    
Good idea to also save the users key encrypted with the admin-key to allow administrative password changes. Please make sure to encrypt the user's key and not the user's password for this purpose. –  Manuel Faux Nov 15 '12 at 18:15
    
Actually, giving it a second look, my description is slightly different from Polynomial's. He used a public key to provide encryption to the data key as an xor'd derivative of the user key. While my described implementation is a little different, I believe it should result in roughly the same security level, though it has slightly different usage properties. –  AJ Henderson Nov 16 '12 at 15:22
    
@AJHenderson Could you review my implementation? Thanks a lot security.stackexchange.com/questions/29183/… –  Surfer on the fall Jan 17 '13 at 13:50

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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