I need to encrypt content in my web application on a per-user basis.
I, the root user, do no开发者_StackOverflow中文版t want to have access to users' content, period.
How can I make it so users are the only ones with access to their content? Perhaps I can make it so a hash of their login password acts as an encryption and decryption key (then their password is stored one-way hashed in my database, and the encryption/decryption hash is generated from their raw password on login and stored in a local cookie)? But what if they change their password? Then I have to update all their content which could take a lot of processing power.
Is there an encryption method that would provide this, without having to re-encrypt their content if their password changes? Something similar to ecryptfs on Linux, perhaps? Is researching ecryptfs a good place to start?
Is making it so only the user can access their content on my servers (and not even me) even feasible?
Process:
- Generate a random secret to encrypt their content.
- Using their provided password encrypt the random secret from #1.
- Store their password as a one-way hash (with salt, maybe multi-hash).
Upon Password change:
- Re-generate the value from step #2.
- Re-generate the hash-cache from step #3.
Upon Login:
- Hash password and check against hash generated in step #3.
- If password matches - use actual provided password to decrypt random secret from #2.
- Use random secret from #2 to unlock data encrypted in #1.
Notes:
- No one can decode the data without knowing the random secret (#1). Random secret can only be unlocked with user's actual password (#2) (short of brute-force). User's actual password is only known in one-way hashed form (#3) so you can confirm it's the same, but cannot decode it and recover #2.
- A forgotten password process is not possible (you can regenerate #3, but random key in #2 is now lost as is everything locked in their vault).
- You don't have to re-encrypt everything in step #1 every time they change their password, only the (simple/quick) random secret from #2.
- If you cache their provided password, or the random secret generated at step 1, or their (decrypted) content anywhere you could cause data leaks.
You're spot on that you need to use their password as a key.
I wouldn't monkey with ecryptfs because an encrypted file system isn't the best solution. You wouldn't want one user's data to be encrypted with the same key that another user used.
When you encrypt the data, you should generate a random string to use as salt. This prevents someone from using a pre-generated list of hashes to decrypt your data. It also changes the hash of two people who might use the same password.
When a user changes their password, you'll have to re-encrypt the data and generate a new salt value. This is the level of security I would expect as a customer, knowing that when I change my password, I'm re-encrypting all of my data to prevent someone from trying to brute force my key.
You can store the salt value in your database unencrypted.
精彩评论