How the encrypt/decrypt sails.js specific model values works? - node.js

I'm reading on Sails attribute documentation the encrypt and decrypt functions for attributes and tested it on a random field alongside with mongodb. This worked well and encrypted the field before saving it on database. So, according to documentation i can decrypt that data with decrypt method. This saves a lot of code validations and library importing. But, i was wondering if is possible:
To be able to verify without decrypt data (Like the compare function on bcrypt library)
To encrypt data on a production db, then change the project (update, replace models or something similar) and then be able decrypt that.
To be able to encrypt data, share the db with another sails project and be able to decrypt (or verify with something related to question 1) the encrypted data.

I just figured it out, seeking for related content on project.
I've found an object called dataEncryptionKeys in /config/models.js file, with the corresponding documentation reference. This answers questions as it is supposed to behave as the key (or keys) for decryption. For the answer of first i think that it will be ok with the decrypt method for most use cases.

Related

Setting up a different encryption key for each record of a model in a Laravel 9 website

Introduction
For a website I'm working on, I will be storing confidential information that I need encrypted.
The way Laravel currently handles things, they encrypt each record with the same APP_KEY that's stored in the .env by default. I think I should be able to take that same APP_KEY and decrypt all the information in my production database as long as I have access to the production .env.
If so, I don't think that's a proper away to handle security for my case. Let's say I hire an admin for my production site and they turn out to be malicious. All they need to do to get access to all the users' sensitive details is take that APP_KEY and run the decryption.
If that's the case, I would rather have it work like this:
The user creates a record that has a "secret" field
A random string is generated to encrypt the data passed to the "secret" field and is then given to the user
If the user wants to access the data in the "secret" field, they have to use the key given to them; I nor anyone else should be able to decrypt that field without knowing the key given to the user
For my specific case, a client program will handle accessing the site's API and storing the encryption key and other details safely, so the user doesn't have to think about this.
My questions are the following:
Is the current encryption scheme Laravel uses safe from malicious admins?
If not, how would I go about best implementing the latter scheme?
Are there vulnerabilities with the latter schema as well, and if so, how can I improve it?
What I've Done
I've looked at the docs on this issue. I've also looked into the Model::encryptUsing feature, which allows for custom encryption.
I think I can implement the above if, when running the action that creates the record, I use Model::encryptUsing, but I haven't tested it yet.
If it ends up working, I will post the answer here.

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:
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).
We can perform search and lookups on encrypted data.
I don't know how to do that but hopefully search for partial words and phrases in encrypted text fields.
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.
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.

Serverless: Handle API key decryption in a lambda function

I am implementing an API that uses a third party library.
The third party library provides a key which needs to be passed in as an input. The key is dynamic and can change based on consumer/business scenario. The lambda function should be able to decrypt the key.
Can someone suggest a way to decrypt a key? I am exploring aws-kms approach on the side.
Please note: i have noted down the .env way of achieving it. But, today my API is being consumed by one consumer hence one API key. Tomorrow, the number will increase (would result into multiple keys) and i may not be in place to store/update the function.
Edit: I need to pass some sensitive information through payload. This can be an alphanumeric value. e.g.
{"sender": "+123", "secret": "encrypted_value"}
The client and server should share a key using which client can encrypt the info and server (lambda function) should decrypt it.
Any suggestion would be great! Thanks!
The standard way of doing something like you described on your "edit" section using KMS is:
Client calls KMS directly to generate a data key. Client will get back a key in its encrypted and plain format.
Client encrypts the data with the plain key, throws it away and send encrypted data and encrypted key to the server.
Server calls KMS decrypt operation, gets back the plain key and uses it to decrypt the data. Server throws away the decrypted key and uses the decrypted data as it wishes.
Please let me know if you meant something different, but this is a fairly standard way to use KMS. Of course, you need to lock down all of the APIs using IAM and KMS policies as your use cases determine.

is client based online encryption practical?

I'm wondering whether a mechanism exists that allows client to client encryption. For example, when enabled, any information that is entered on one client can only be decrypted using a specific key.
Similar to how regular public key transactions work, but server agnostic.
A use case:
Everything on my Facebook profile is encrypted, and no body would be able to view that information (not even facebook). The users that I give the key would be able to decrypt that information.
This would allow complete control of data stored online.
The same idea can be applied for pictures uploaded to the internet.
One issue that I see is to have a practical mechanism to manage keys and a secure way to distribute keys to other users.
Has anyone done something like this before?
In case of Facebook I can imagine encrypting the data with OpenPGP keys into armored (text) format. Then you can place encrypted block to facebook or anywhere else. Other users would take the block, decrypt it on the client side and see it.
The same applies with other social networks and places where you can store some text block.
You can easily do encryption in some client application and even in Javascript (if you manage to make JavaScript load local user's keys somehow).

How to save the confidential data at server side

I create a web server with Node.js. The database is MongoDB. I'm using a json file to save the server configuration. The node module 'nconf' is used to read the json file.
Currently, all the data, including some confidential data, saved in the json file is plain text. I don't think it is security enough. What should I do to make sure the confidential data is security?
You could take a look into the crypto library of node.
Here is a link to the documentation: Crypto Node.js
You could use this to encrypt some of the data that is contained within the file. But you should also probably consider removing the sensitive information and find another means to store it else where, perhaps within a database, like your MongoDB.

Resources