UNPKG

excryptor

Version:

Node JS Express Framework Cryptor Tool

103 lines (79 loc) 3.56 kB
// AES Encryption/Decryption with AES-256-GCM using random Initialization Vector + Salt // ---------------------------------------------------------------------------------------- // the encrypted datablock is base64 encoded for easy data exchange. // if you have the option to store data binary save consider to remove the encoding to reduce storage size // ---------------------------------------------------------------------------------------- // format of encrypted data - used by this example. not an official format // // +--------------------+-----------------------+----------------+----------------+ // | SALT | Initialization Vector | Auth Tag | Payload | // | Used to derive key | AES GCM XOR Init | Data Integrity | Encrypted Data | // | 64 Bytes, random | 16 Bytes, random | 16 Bytes | (N-96) Bytes | // +--------------------+-----------------------+----------------+----------------+ // // ---------------------------------------------------------------------------------------- // Input/Output Vars // // MASTERKEY: the key used for encryption/decryption. // it has to be cryptographic safe - this means randomBytes or derived by pbkdf2 (for example) // TEXT: data (utf8 string) which should be encoded. modify the code to use Buffer for binary data! // ENCDATA: encrypted data as base64 string (format mentioned on top) const _crypto = require('crypto'); const options = { key: "1" }; const _default = { length: 32, // default 32 type: 'utf8', // default utf8, } module.exports = master; module.exports.encrypt = encrypt; module.exports.decrypt = decrypt; module.exports.ciphers = ciphers; module.exports.hashes = hashes; function encrypt(text) { // random initialization vector const iv = _crypto.randomBytes(16); // random salt const salt = _crypto.randomBytes(64); // derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for // a large number of iterations. It may can replaced by HKDF const key = _crypto.pbkdf2Sync(options.key, salt, 2145, 32, 'sha512'); // AES 256 GCM Mode const cipher = _crypto.createCipheriv('aes-256-gcm', key, iv); // encrypt the given text const encrypted = Buffer.concat([cipher.update(text, _default.type), cipher.final()]); // extract the auth tag const tag = cipher.getAuthTag(); // generate output return Buffer.concat([salt, iv, tag, encrypted]).toString('base64').toString('hex'); } function decrypt(encdata) { // base64 decoding const data = Buffer.from(encdata, 'base64'); // convert data to buffers const salt = data.slice(0, 64); const iv = data.slice(64, 80); const tag = data.slice(80, 96); const text = data.slice(96); // derive key using; 32 byte key length const key = _crypto.pbkdf2Sync(options.key, salt , 2145, 32, 'sha512'); // AES 256 GCM Mode const decipher = _crypto.createDecipheriv('aes-256-gcm', key, iv); decipher.setAuthTag(tag); // encrypt the given text const decrypted = decipher.update(text, 'binary', _default.type) + decipher.final(_default.type); return decrypted; } function master(key) { options.key = key; return function resolve(req, res, next) { next(); } } function ciphers() { return _crypto.getCiphers(); } function hashes() { return _crypto.getHashes(); }