As the title implies, I would like to design a secure file storage/sharing platform. This is an abstract design question, so details regarding programing languages or platforms are not particularly relevant, unless they represent the only option for a good design.
So, the application has to simultaneously fulfil all of the following conditions:
- No data of any kind can be stored on local user devices (ie laptop, phone, etc), except during the current session
- The user can access the file on demand from any device
- The server or unauthorised users cannot read the stored file
How should I design such an application in a reasonable way? And by rasonable I mean the environment of known threats, and the biggest risk is human error, such that if a leak ever happens, it is limited to 1 file per 1 user, and not all user files, or the whole database.
So far, I have the following ideas regarding the design:
- The user accesses the app though standard HTTPS
- The user registered an account with a Username and a Password
- The server stores the Username and Hashed+Salted password
- When the user wants to upload a file, the following steps will happen for each individual file:
- The frontend (mobile app / webpage / other) will ask the user for a file specific password
- The frontend will generate a keypair and secure the private key using the user provided password
- The frontend will encrypt the file using the public key
- The server receives and stores: The encrypted file, the public key, the secured private key and the password hash for the specific file
- Any information is deleted from local storage on user side
- When the user wants to view a file, the following steps will happen for each individual file:
- The user will login to his account using username and password
- The credentials will be validated by the server
- User inputs a filename and a password in the frontend
- The frontend sends a request with a filename and a password
- The server looks for the filename, and compares and validates the password against the corresponding stored hash
- If valid, the server sends the encrypted file, the public key and secured private key back to the user
- The frontend decrypts the file using the private key and password, and shows data to the user.
- Once the session is over, data is deleted from local storage on user side.
Is this a secure setup or is it useless/overkill? My biggest concern is storing private keys on the server. Does this even make sense? Is a password enough to secure the private key, or can it be used to recover data even without knowing the password? What are other options if such exist?
There is also a 4th, not mandatory condition, that the user should be able to share a specific file with another trusted user. Now, for this, I have thought of the following approache: First approach is creating a copy for the other user (future changes to data will not be reflected):
- Upon creating a share request, the owner of the file (User 1) (assuming the file is already received from server) requests a public key from User 2
- User 2 generates a password and key pair which are sent to the server
- Server send the received public key to user 1
- User 1 encrypts the file using public key from user 2, and sends it to the server
- User 2 can now access the file as previously described
My concern about this setup (in addition to the issues from the first part), will it increase the chances of extrapolating the contents of the file and bypassing encryption entirely, if the number of copies is large enough? Or is it not a concern?
Edit 1: To provide an example, You can imagine a patient storing some medical records, in a confidential manner, such that not even the server can read them. And wanting to share, with the doctor, such that only him and the doctor can view them.
I understand this is a very abstract question, so please feel free to request details/improve the question. To summarise, what would be a good practice for such requirements, if even possible? Is the design described above secure? what are other options?