4
votes

I want to encrypt the data I store in Firestore database. Let's say you encrypt data with a 256 bit AES key derived from a user password and you encrypt the AES key using a single Google KMS key.

Is this enough? Or do we need to use somesort of private-public cyptorgraphic library like RNCryptor locally.

In my case all my app data is stored in Firestore and have supporting cloud functions (node.js). A good chunk of user data needs to be encrypted.

Every user will have a unique AES key generated this way below on login. The key would be generated on their first login -- or registration, and the AES key post encryption using the KMS key, will be saved in Firestore itself. When decryption is needed, the KMS key will be used to decrypt the AES key, then use it.

String password  = "password";
int iterationCount = 1000;
int keyLength = 256;
int saltLength = keyLength / 8; // same size as key output

SecureRandom random = new SecureRandom();
byte[] salt = new byte[saltLength];
randomb.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt,
                    iterationCount, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory
                    .getInstance("PBKDF2WithHmacSHA1");
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
SecretKey key = new SecretKeySpec(keyBytes, "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[cipher.getBlockSize());
random.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivParams);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8"));

(code reference: "Using Password-based Encryption on Android " article)

Just one thing there is no concept of a end-user-side app, and service provider app in my use case. There is just one app, and firestore backend, and server-side cloud functions powered by node.js. I am trying to see if I can produce a strong system free from hacks, to store encrypted stuff (prevent admins from viewing the same also using console dashboard -- for private data). I will be ensure the Google KMS key can't be accessed directly but it will saved in another user account.

"The KMS key belongs to a different Google account to the Firebase database, so no one user (e.g. me) has permission to both read the data AND decrypt it. A hacker would need to compromise both accounts to access the unencrypted data."

Strategy Reference HOW TO ENCRYPT A GOOGLE FIREBASE REALTIME DATABASE

2

2 Answers

1
votes

Official response I got from Google Firebase support team:

Currently, custom access to Firebase (e.g. access to Firestore, RTDB) is not yet supported, but a highly requested feature. Also, as you may know, Firestore client SDKs do not have encrypting capabilities. So additional encryption done won’t hurt (I cannot suggest that much on this part). To add, having a strict security rules is a must.

0
votes

You don't have to do it generally because it's encrypted automatically.
https://cloud.google.com/firestore/docs/server-side-encryption
It's free from cracks already!