I am working on application that allows users to upload files containing company data and then share those files with a list of other users that have specific roles within the system.
I want to encrypt the uploaded files to protect the data at rest while allowing the files to be shared by people who do not know the encryption password. The uploaded files are owned by the company that they belong too not by the user who uploads them.
- When a user creates an account on the system a private-public key pair is generated for the user, the private key is stored in the database and is encrypted with the users clear text password, which is accessible during the login process. User passwords are salted, , stretched hashes so other than during login the app does not know the clear text of the users password.
- When a user log's into the system successfully the encrypted user's private key is pulled from the database, decrypted and the private decrypted key is stored in the http session. I am assuming that while the decrypted private key is in RAM it going to be very hard but not impossible for a hacker to get a private key out of the RAM of a running process.
- When a user uploads a file the following happens:
- A secure random UUID is generated and used as the password to encrypt the uploaded file using AES 256
- The generated UUID is then encrypted with the user's public key and stored in the database.
- The system determines a list of every user that can access that file
- For every user that can access the uploaded file the generated UUID is encrypted with that user's public key and the encrypted UUID is stored in the database.
- When a file is being downloaded here is what the system does.
- It locates the encrypted password for the file being downloaded
- Decrypt the encrypted password using the user's private key
- decrypt the file using the file password
- return the clear text of the file to the user
To me this seems to be more secure than just storing the files on the server unecrypted a hacker who steals a copy of the data would not be able to read the files, since they would have to figure out the clear text passwords of the users before they could get at the user's private key.
The problem is dealing with password rests, since the users private key is encrypted with the users password if the user forgets their password and does a password reset they would loose their private key and thus access to the files they uploaded. Since I need to have a password rest feature in the application I am into a chicken and egg scenarios because how do I safely store the private keys of the users without end result being less secure than doing nothing?
Is there any way to store private keys that are encrypted with a users clear text password and still have a way when resetting a password to preserve access to the users data?
I am not a security expert and would prefer to use a known solution / library for this problem but I can't seem to find any so I have to make my own solution.