Skip to content

Instantly share code, notes, and snippets.

@bllohar
Created September 25, 2017 06:52
Show Gist options
  • Save bllohar/28ee29b3304d8bf6dbc11d1b16b00130 to your computer and use it in GitHub Desktop.
Save bllohar/28ee29b3304d8bf6dbc11d1b16b00130 to your computer and use it in GitHub Desktop.
Nedb Encryption & Decryption
var Datastore = require('nedb')
const path = require('path')
var crypto = require('crypto');
var assert = require('assert');
var algorithm = 'aes256';
var key = 'password';
var db = {}
db.bookinghistories = new Datastore({
filename : path.join(__dirname, 'data/bookinghistories.db'),
autoload: true,
afterSerialization: function (doc) {
console.log(doc);
var encrypted =doc;
try{
var ef;
if(JSON.parse(doc) && isNaN(doc)){
var cipher = crypto.createCipher(algorithm, key);
encrypted=cipher.update(JSON.stringify(doc), 'utf8', 'hex') + cipher.final('hex');
ef = encrypted;
console.log("Ser" +encrypted);
return encrypted;
}
}catch(e){
}
da=encrypted;
},
beforeDeserialization : function(doc) {
console.log(doc);
if (doc != undefined && doc != "") {
var decipher = crypto.createDecipher(algorithm, key);
var decrypted = decipher.update(doc, 'hex', 'utf8') + decipher.final('utf8');
console.log("decipher" + decrypted);
return decrypted;
}
//console.log("decipher2 " + da);
return da;
}
});
@reigelgallarde
Copy link

    afterSerialization: (data) => {
        var cipher  = crypto.createCipher(algorithm, key);
        data   = cipher.update(JSON.stringify(data), 'utf8', 'hex') + cipher.final('hex');
        
        return data;
    },
    beforeDeserialization: (data) => {
        
        var decipher = crypto.createDecipher(algorithm, key);
        data = decipher.update(data, 'hex', 'utf8') + decipher.final('utf8');
        
        return JSON.parse(data);
    }

@jordanbtucker
Copy link

I came across this while looking for a library that does this natively. Here's what I'm using now.

{
	afterSerialization (plaintext) {
		const iv = crypto.randomBytes(16)
		const aes = crypto.createCipheriv('aes-256-cbc', key, iv)
		let ciphertext = aes.update(plaintext)
		ciphertext = Buffer.concat([iv, ciphertext, aes.final()])
		return ciphertext.toString('base64')
	},
	beforeDeserialization (ciphertext) {
		const ciphertextBytes = Buffer.from(ciphertext, 'base64')
		const iv = ciphertextBytes.slice(0, 16)
		const data = ciphertextBytes.slice(16)
		const aes = crypto.createDecipheriv('aes-256-cbc', key, iv)
		let plaintextBytes = Buffer.from(aes.update(data))
		plaintextBytes = Buffer.concat([plaintextBytes, aes.final()])
		return plaintextBytes.toString()
	},
}

Note that I don't process any JSON because there's really no need to since afterSerialization takes a string and beforeDeserialization returns a string.

Also, an IV is generated for each record and stored as the first 16 bytes. All records are stored as Base64 when encrypted.

key is generated using Scrypt, so a password can be used to encrypt and decrypt, but you can use any secure value for key.

@kailashyogeshwar85
Copy link

@jordanbtucker Where u prefer to store the key for future use.

@jordanbtucker
Copy link

jordanbtucker commented Jun 2, 2020

@kailashyogeshwar85 I don't store the key. I use scryptsy to generate the key with a password each time the app is started.

If you do need to store the key, you can use a package like keytar to store the key using the system's keychain/credential vault.

@kailashyogeshwar85
Copy link

@RHeijnen
Copy link

RHeijnen commented Jun 15, 2020

@jordanbtucker
Hey Jordan, I know this really is not the place - but care to share more about that ? I am trying to achieve the same thing but running into several issues originating from my lack of experience in crypto.

An basic explenation would be very much appreciated!

@jordanbtucker
Copy link

@RHeijnen I created my own gist. It has two examples: one that prompts the user for a password each time the app starts, and one that stores the password in the system keychain. Both examples are heavily documented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment