Enhancing Security by Splitting Key in Different Places
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:
- Compute
uk
from the user password andus
. - Xor
uk'
withuk
to retrievedk
. - Decrypt
c
usingiv
anddk
, giving usm
.
The admin decryption works as follows:
- Compute
ak
from the admin password andas
. - Decrypt
P
usingAES_Decrypt(P', ak)
- Decrypt
dk
usingRSA_Decrypt(dk', P)
- Decrypt
c
usingiv
anddk
, giving usm
.
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.