1

My goal is to be able to encrypt the data so that no one would be able to make use of it if it was stolen.

User data
- the one that will be encrypted
- can be any type of data

Data encryption key
- the key for encrypting and decrypting the user data
- stored encrypted
- does not change
- unique per user
- generated upon registration
- has two encrypted copies:

  • 1st is encrypted and decrypted using the user's unencrypted password
  • 2nd is encrypted and decrypted using the user's email

User password
- used to encrypt and decrypt the 1st copy of data encryption key
- stored encrypted using bcrypt

User email
- used to encrypt and decrypt the 2nd copy of data encryption key
- has a separate copy stored encrypted using bcrypt. The other copy was part of user data

[LOGIN]
When the user logs in, the submitted password will be verified using the stored encrypted password. If valid, his/her data encryption key will be decrypted using the same submitted password. The data encryption key can now be used to encrypt and decrypt the user data.

[CHANGE PASSWORD]
The user provides his old password. This will be used to decrypt the data encryption key which will then be encrypted using the new password.

[FORGOT PASSWORD]
The user is required to provide his username and email. This username will be used to find the separately stored encrypted email which will be used to verify the provided email. If both username and email are correct the provided email will receive a reset key. The reset key will allow the user to provide a new password. The 2nd data encryption key will be decrypted using the email and will be encrypted using the new password. The resulting value will replace the 1st data encryption key.

I am wondering if this is a viable scheme. I have not yet looked for a similar approach. If you know one, or has a better one please let me know.

Gene Diaz
  • 113
  • 4
  • 2
    I'll assume this is for personal use. The usual overwrought commentary about home-brewed solutions in production environments will rain down otherwise. – LateralFractal Oct 13 '14 at 12:49
  • 1
    Is all of this done client side? Where is the encryption key stored? – RoraΖ Oct 13 '14 at 12:49
  • This is done on the server side. I would like to know if there is already a standard for this type of schemes. – Gene Diaz Oct 13 '14 at 13:29

1 Answers1

1

So if I have your goals correct - you want to protect user data and you want their data to be recoverable if they lose their login password.

The basics: There is stuff you know; stuff they know; and stuff you both know.

Preferably for encryption of their data on your system to really make any sense, it needs to be protected by something you don't know - at least not all the time.

Putting aside password/account recovery for the moment, the simplest method is to only keep and match a salted hash of their password but cache their reentered password as temporary session data for decrypting/accessing/modifying their content while they are logged in. Discarding the session data when they log out or timeout.

Password recovery where serious data encryption is involved should be the user's responsibility, as hand-holding on this particular issue undermines the very security you are hoping to provide. Your website or application should provide backup options for their password, such as a QR code they can print out. Having this recovery option as a different password or credential doesn't really make any sense in this case as their data is only, at heart, encrypted by one symmetric key. You can also have a separate channel, credential or mechanism that is one-shot or email based for recovering their account but not their data. That distinction must be made clear to them. No password, no backed-up hardcopy - no data recovery.

The main concern of the initial approach you have outlined is that the roles and responsibilities of their data security is muddled. You should host their data in fashion useful for the website or app when they are logged in but they should retain the only credential to access their data. Bcrypt is a roundabout way of storing their data on your system without encryption; as all the information needed to crack it is already persistently on the server.

Naturally if the encryption/decryption occurs client-side then the security risk for the user is even less - but that depends heavily on how the website or app needs to use their data, so that may not be a practical option.

LateralFractal
  • 5,143
  • 18
  • 41
  • everything is done on the server side. I'll put your answer in mind. Any chance you could provide me with a similar scheme that is already used in production? – Gene Diaz Oct 13 '14 at 13:36
  • You'd have to ask the implementation fellas over in Stack Overflow unless some else here has an idea. It's a pretty common design pattern, to fetch encrypted data with key in perhaps a HTTPS session cookie or something. – LateralFractal Oct 13 '14 at 13:48