-
-
Save bllohar/28ee29b3304d8bf6dbc11d1b16b00130 to your computer and use it in GitHub Desktop.
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; | |
} | |
}); |
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);
}
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
.
@jordanbtucker Where u prefer to store the key for future use.
@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.
@jordanbtucker thanks
@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!
@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.
Do you test with a large of database?