1

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:

  1. No data of any kind can be stored on local user devices (ie laptop, phone, etc), except during the current session
  2. The user can access the file on demand from any device
  3. 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:

  1. The user accesses the app though standard HTTPS
  2. The user registered an account with a Username and a Password
  3. The server stores the Username and Hashed+Salted password
  4. 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
  1. 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):

  1. 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
  2. User 2 generates a password and key pair which are sent to the server
  3. Server send the received public key to user 1
  4. User 1 encrypts the file using public key from user 2, and sends it to the server
  5. 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?

4
  • If you really need to encrypt it, make sure the server can never unencrypt it. That requires the user who uploads to be the only one who knows the master password for the encryption. They would then need to communicate that, securely, with anyone they share the file with. (That's their responsibility, not yours since you are only serving encrypted data.) Your server can manage who gets access to the file, but the uploading user would be the one providing any key necessary to unencrypt.
    – pcalkins
    May 10, 2022 at 20:07
  • So the concern is not local storage at all. It's getting rid of the master password/key server-side after it is used. (make sure it's cleared from memory, logs, etc... after it is used)
    – pcalkins
    May 10, 2022 at 20:12
  • I think this question is way too broad to be able to have a reasonable answer in 1 to 2 paragraphs. Maybe you could break this down into multiple posts that each focus on a single aspect of the question? May 10, 2022 at 20:49
  • In the past, Upspin (github.com/upspin/upspin) can be hosted GCP instance. It also has fine grain access control to share files. It didn't have a UI so I don't think it completes your design requirements, but maybe it can help you jumpstart your design.
    – 杜興怡
    May 11, 2022 at 0:26

2 Answers 2

0

While I can believe this construction leads to a system where not even the server can read the contents, it is instead beset by a much bigger problem, humans.

Passwords are awful. A different password for every file the user has? I give the average user 2 or 3 documents before the password is 1234. All an attacker needs is to dump encrypted files and run dictionary attacks.

It's okay to store encrypted files in a way that the server can decrypt them, when handled properly (KMS, carefully curated admin lists, least privileged, etc). If it must be encrypted in a way the server cannot decrypt it, properly generated and user managed key material is a much stronger proposition.

0

If by "leak" you mean someone else getting control of the server in your formula, then the database could encrypt the files before transferring them to the server.

For encryption you can use the public key of the user certificate. That means you need to employ HTTPs with mutual auth on the server and provide the database a copy of the trust store. This would eliminate the need for a password on every file transfer to the user.

You can use the same approach for user file sharing by using a client app capable of the encryption step above and having access to the trust store containing user certificates.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .