title: Encrypt your firestore data
body: <p>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. </p>
  
  <p>Is this enough? Or do we need to use somesort of private-public cyptorgraphic library like RNCryptor locally.</p>
  
  <p>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.</p>
  
  <p>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. </p>
  
  <pre><code>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></pre>
  
  <p>(code reference: <a href="https://nelenkov.blogspot.com/2012/04/using-password-based-encryption-on.html" rel="nofollow noreferrer">"Using Password-based Encryption on Android 
  " article</a>) </p>
  
  <p>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. </p>
  
  <p>"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."</p>
  
  <p>Strategy Reference <a href="http://www.geero.net/2017/05/how-to-encrypt-a-google-firebase-realtime-database/" rel="nofollow noreferrer">HOW TO ENCRYPT A GOOGLE FIREBASE REALTIME DATABASE</a></p>