node.jsmongodbencryptionmongoose-plugins

Mongodb community - at rest data encryption in node js


I'm looking for a way to encrypt the entire DB and keep the ability to search for data although it's encrypted.

I have seen a lot of questions regarding encryption of at rest data in Mongo, but none of it got an answer that can help one complete a full flow for their application. I hope to present here my findings and get feedback and more ideas (I still have some questions).

Encryption options:

1.mongoose-encryption. Complete solution! Can encrypt all fo the db with minimal work for you!.
2. Procona mongodb - I didn't had a chance to test it, I've spent hours trying to install and get it to run, without luck (this is probably just me though..).
3. Create get and send methods to encrypt and decrypt your data in the Module level.

My requirements for at rest data encryption are:

  1. Application layer does not need to be involved in the encryption- decryption process. Should be like we don't even have the data encrypted (for the most part).
  2. We can perform search and lookups on encrypted data.
  3. I don't know how to do that but hopefully search for partial words and phrases in encrypted text fields.
  4. Of course that all data is encrypted expect for Object IDs.

My approach:
I want to try and use mongoose-encryption to use all the benefits of this amazing plugin.
I also want to add to the schema the Hash of the Real value in the encrypted field so I could preform find operations on encrypted field.

The problem: I can't seem to find the correct mongoose Hook to temper with the non-encrypted data before mongoose-encryptions hides it. So I can't generate my Hash.

This doesn't work:

Users.pre('save', () => { 
  this.hashedName = hash(this.name)
  console.log(":(")
});

Also as mentioned above, searching for partials and phrases in encrypted data. With my approach we could find someone named "Danielle" but we can't search in Hash for users with a name that starts with "Dani".

Please give me your opinion as well for my approach. I know that this is a topic without easy to find solutions.


Solution

  • If you want to encrypt the data on disk, encrypt the entire disk and encrypt the swap. If someone gets a copy of the database (e.g. you forgot to put auth on the database and someone connects to the database and dumps the data) the plaintext is exposed.

    If you want the database to store encrypted data only, use client side encryption. This requires key management on the client side but makes it so that someone dumping your database doesn't get the plaintext.