1

I am building an Electron app and implementing Cloud Storage support. Users can upload files within my app to their account. Me, as an admin, I don't want to be able to read the files through the Firebase admin console. I also want to avoid a user password as people might forget it. Just logging into their account should be enough to access their files.

In my prototype I store user files in data/${user.uid}/. But now I am stuck and don't know which password I should use to encrypt the files.

There are a few questions around this topic which involve DigitalOcean which looks too overkill for what I am doing. Is there anything else I could use as a password that is part of the User object that is not exposed anywhere else?

HelloWorld
  • 2,392
  • 3
  • 31
  • 68

1 Answers1

2

I came across multiple options for Client Side Encryption in File Storage in Firebase. The encryption itself is simple enough to perform with existing libraries, using a symmetric key (a key that can both encrypt data, and decrypt the encrypted data). As the usual problem goes, we now need to find a secure place to store this all-powerful key.

Option 1 : Store Key on User Device

Pros : This stores the key on the user’s device, so the key is never in the application servers. Cons : The key, and therefore the data, is not accessible from other devices. It’s not a bad solution depending on the use case and situation.

Option 2 : Google Key Management Service for Encryption

Pros : Encrypting the key with another data key stored in Google Key Management Service. The user’s key encrypts the data, and then the key is encrypted by a KMS key and stored in the database. As Andy rightly points out in his blog, that the KMS key belongs to a different Google account to the Firebase database, so no one user has permission to both read the data and decrypt it. A hacker would need to compromise both accounts to access the unencrypted data. Cons : User has to manage two accounts.

Option 3 : Stash the Key in User’s Google Account

Pros : When the user logs in, we get the OAuth credentials to request the user’s personal encryption key, or create one if we can’t find one, from the user’s Google account. This way, the key is always fully in the user’s possession, but they never have to deal with it directly. Google Drive provides an API for creating a special application data folder (user consent is required during OAuth). The contents of this folder are not visible to the user, and is only accessible via your application’s credentials. Cons : User has to be cautious not accidentally deleting their own encryption key.

Option 4 : Asymmetric Key Pair

Pros : User first gets the public keys of the recipients. He then generates a symmetric key for himself with which he encodes the file. He then creates a copy of this symmetric key for each recipient and encrypts it with the respective public keys. Finally, he transfers the encrypted copies of the symmetric key together with the encrypted file to the server and stores them there.If another user wants to download the file, he gets it in the encrypted form together with the copy of the symmetric key that is encrypted for him. He can decrypt the latter using his private key and now has the symmetric key with which he can decode the file.

Option 5 : Public and Private Key Encryption

Pros : Create private & public keys for your users when you sign them up. Encrypt data on User 1's device with User 2's public key. Store the encrypted data in your database. When User 2 reads up the encrypted data, his/her private key will be able to decrypt it.

Priyashree Bhadra
  • 3,182
  • 6
  • 23
  • That's a fantastic answer! Thank you very much for the insights! Personally, I prefer to avoid asking the user to store a key somewhere. It often gets lost and losing data is not worth it. Option 3 seems to be the most interesting option whereas I am not sure if that still works if the login is made through Twitter or Facebook – HelloWorld Aug 02 '21 at 21:51
  • Something that just crossed my mind. I was wondering if it is suitable to hash the user `uid` and use this as a directory name on the server. This means, since I never see the original `uid` my app could use this as a password. – HelloWorld Aug 02 '21 at 21:52
  • Seems interesting. Were you successful in doing this? – Priyashree Bhadra Aug 09 '21 at 06:52
  • Unfortunately not yet. I am rolling out my application in the next 2-3 months. I set a reminder, I will update you on this topic if this option is the one I go with (or not and why) – HelloWorld Aug 11 '21 at 21:34