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?
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.