End to end encryption with Firestore - firebase

Is there any recommended way to encrypt data in Firestore? Even though Firestore, by default, encrypts data before it writes to the disk, admins still can read data in the console. I am looking to make the data readable only by users who are allowed decrypt it. So it will be unreadable in the console.
One way I think it may be possible is to use cloud functions but I can't find how to modify the data before it gets saved to the disk (beforeWrite hook).

The only way to control all access to all data in Firestore (or Realtime Database for that matter) is to perform encryption on the raw data itself before it's even passed to the client APIs or SDKs that perform the write.
It's not possible to hook writes before they actually commit to storage with Cloud Functions. A function will only receive an event after the data is successfully written.
Also, bear in mind that if you encrypt data before it reaches the API, you will be unable to search and sort using that data, because it will no longer represent the original data in any way. All you would be able to do is access a document/location by its unique key (assuming that key is also not encrypted, or the encrypted id is (cryptographically) shared between both parties through another secure channel.

You'll need to encrypt data on the client devices before you write them into Firestore. When the other device reads up the data, decrypt it.
Key management is what you'll need to spend some time with to implement: Users on both devices need to have private keys locally and public keys accessible to the other users to encrypt messages with. Then you'll need to create a data encryption key to encrypt/decrypt messages in the chat room. This data encryption key, you'll encrypt with the participating users' public keys. And all keys, store in Firebase, encrypted.
Check out these 2 sample apps for a Firestore chat app example:
iOS: https://github.com/VirgilSecurity/demo-firebase-ios
Android: https://github.com/VirgilSecurity/demo-firebase-android
David

Related

How to implement Firestore data encryption?

I have actually one SPA in ReactJs + one mobile application in Flutter + one REST API developed with SailsJs running on a separate server. I managed user authentication with the secured session cookie generated by Firebase Authentication sent back by the API when we are login with valid information (id/password).
Now, I want to encrypt highly sensitive data (medicines, treatments, patients) in the Firestore database so no one can see the data in clear when an intrusion happens or with the basic admin access to the console for the production database.
Do I need to encrypt the data at the client-level considering the fact that the connection between the clients and the API server is over HTTPS? Or can I just encrypt the received body at the api-level before storing it in Firestore and decrypt the encrypted data at the GET endpoints?
My idea is to generate an encryption key with AES at the user registration and store it in another database from an European/French hosting company in order to avoid any risk with the US Cloud Act or whatever (user id from Firebase Authentication <-> encryption key). Is it a good idea? What other solution can I choose to securely store and use the encryption keys of my users?
Thanks for your help.
Do I need to encrypt the data at the client-level considering the fact that the connection between the clients and the API server is over HTTPS? Or can I just encrypt the received body at the api-level before storing it in Firestore and decrypt the encrypted data at the GET endpoints?
If you encrypt/decrypt the data in your custom API, that API will need to have access to the encryption keys. While the chances are small, it does mean the keys could be taken from here, and then be used to compromise the data.
If you encrypt/decrypt the data in the client-side code, only that code will need access to those keys. If you then exchange the keys through some out-of-band mechanism, something that doesn't get stored on your servers along the way, there is no way for anyone with access to those servers to decrypt the data.

Exported firebase cloud firestore data to cloud storage, data is encrypted how to use now?

I exported my cloud Firestore database to a cloud storage but, I can’t verify it will be able to use as a backup since data looks encrypted. My question is, will I be able to decrypt somehow or am only limited to GCP processes to decrypt the data in case I need it as a back up
The data is not encrypted, it's just serialized in a special format. You can take those exports, copy them around, and re-import them from a different bucket to a different database. You will have to use one of the documented methods here or here, else figure out how to parse the data yourself (which is not documented, but they are probably protobufs).

Is there any way to search through encrypted data in firebase firestore?

I am developing a react native app and using firebase firestore as a centralized database. Before placing user data on firestore I am encrypting the data using crypto js. Now I want to search through the database the problem is that the data is encrypted and when I try to encrypt the same data again crypto js creates different encrypting data. Is there any way possible to search through the encrypting data in firebase without loading the data in the mobile app and then decrypting it?
Firestore does not support searching encrypted data. If you encrypt it on the way in, you will have to decrypt it on the way out before you can know anything about the data you've stored.

Cloud Firestore Offline Encryption

Does anyone know if the local cache of the Firebase Cloud Firestore is encrypted at rest on the clients? I want to temporarily store sensitive details (think payment details) in the datastore until network connectivity becomes available and I can fire off some cloud functions and dispose of the data. I could go about encrypting the data before it is stored, but then that necessitates the need to rotate keys etc.
The google group responded, and the answer is no. The store is not encrypted on the device. This facilitated the need for encryption prior to storing the data.
https://groups.google.com/forum/m/#!topic/google-cloud-firestore-discuss/fa4RygAeFJg

Is it necessary to encrypt chat messages before storing it into firebase?

As far as I know, Firebase sends data over an HTTPS connection, so that the data is already being encrypted. Although Firebase provides security rules to protect my data structure, I can still be able to see the string messages in the database.
I'm just curious whether it is a good idea to encrypt messages before pushing the data to Firebase or not.
Should I just move on from this topic to something else?
Thank you.
You seem to have a good grasp of how Firebase Database works: the data is encrypted in transit, and it is stored on encrypted disks on the servers. If you enable local persistence on the device, the on device data is not encrypted.
But administrators of the app can see the data in the Firebase console. If it is a requirement of your app that administrators can't read this data, then you'll need to encrypt it on the client before sending it to Firebase. A while ago a developer explained their end-to-end encrypted chat on the firebase-talk mailing list.
Hey Jeff: you're right that when you write some data into Firebase/Firestore, the data:
Is protected over the wire using HTTPS.
Then, when it lands on the Firebase REST frontend server, HTTPS terminates and the server has access to the full payload
Then the REST server routes the data to the backend/database, which also has access to the data.
When the data is written into disk, it's encrypted at-rest, but the at-rest encryption keys are also available to Google and your administrators will also see the Firestore contents
Encrypting data client side (End-to-End Encryption) prohibits all these participants/roles seeing your data.
Encrypting data on client side is fairly simple (compatibility across mobile platforms and browsers is tricky). The other tricky part is the key management to enable one user access to the decryption key without the other user sending the key over in an unsecure channel.
The way you can implement this is:
Create private & public keys for your users when you sign them up
Encrypt data on user1's device with user2's public key
Write the encrypted data into Firestore
When user2 reads up the encrypted data, her private key will be able to decrypt it.
Check out this Firebase E2EE chat sample on GitHub for iOS: https://github.com/VirgilSecurity/demo-firebase-ios and Android: https://github.com/VirgilSecurity/demo-firebase-android
HTH,
David

Resources