Recently I published a post on AWS KMS encryption using .net / .net core. Now I got a chance to work on AWS KMS encryption using Node.Js. Following is the Node.Js version of the KMS helper class given in the previous post.
I used the aws-sdk npm for this
I used the aws-sdk npm for this
encrypt.js
'use strict'; var AWS = require("aws-sdk"), crypto = require('crypto'), algorithm = 'AES-256-CBC'; var awsconfig = { "accessKey": "<Your AWS Access Key>", "secretAccessKey": "<Your AWS Secret Key>", "region": "<Your AWS region>", "cmkArn": "<Your KMS master Key arn >" // The identifier of the CMK to use to encrypt the data key. You can use the key ID or Amazon Resource Name (ARN) of the CMK, or the name or ARN of an alias that refers to the CMK. } // Creates the KMS client function getKMSClient() { var credentials = new AWS.Credentials(awsconfig.accessKey, awsconfig.secretAccessKey); AWS.config.update({ region: awsconfig.region, credentials: credentials }); return new AWS.KMS(); } // Generates the KMS data Key function generateDataKey() { const kms = getKMSClient(); return new Promise((resolve, reject) => { const params = { KeyId: awsconfig.cmkArn, KeySpec: 'AES_256'// Specifies the type of data key to return. }; kms.generateDataKey(params, (err, data) => { if (err) { reject(err); } else { resolve(data); } }); }); } // Decrypt the KMS Data key function decryptDataKey(CiphertextBlob) { const kms = getKMSClient(); return new Promise((resolve, reject) => { kms.decrypt({ CiphertextBlob }, (err, data) => { if (err) { reject(err); } else { resolve(data); } }); }); } module.exports = { encrypt: function (text) { return new Promise((resolve, reject) => { generateDataKey().then(dataKey => { // Get a random IV const iv = crypto.randomBytes(16); // Copy the length of the CiphertextBlob as first byte and concatenate the CiphertextBlob to it var length = Buffer.from(['0x' + dataKey.CiphertextBlob.length.toString(16)]); var str = Buffer.concat([length, dataKey.CiphertextBlob]) // Concatenate the iv to the buffer str = Buffer.concat([str, iv]); // Create aes encryptor with KMS plain key var encryptor = crypto.createCipheriv(algorithm, dataKey.Plaintext, iv); // Encrypt the data encryptor.write(text); encryptor.end(); // Concatenate the encrypted to the buffer and return the base64 string str = Buffer.concat([str, encryptor.read()]); resolve(str.toString('base64')); }, error => { reject(error); }); }); }, decrypt: function (text) { return new Promise((resolve, reject) => { try { // Convert the base64 string to buffer var buf = Buffer.from(text, 'base64'); // Get the CiphertextBlob length stored in the firsty byte var length = parseInt(buf[0].toString()); // Extract the CiphertextBlob, IV and var cipherBlob = buf.slice(1, length+1); var iv = buf.slice(length + 1, length + 1 + 16); var encText = buf.slice(length + 1 + 16, buf.length); // Decrypt the CiphertextBlob and get the plaintext key decryptDataKey(cipherBlob).then(dataKey => { // Create aes decryptor and decrypt the text var decryptor = crypto.createDecipheriv(algorithm, dataKey.Plaintext, iv) decryptor.write(encText); decryptor.end(); resolve(decryptor.read().toString()); }, error => { reject(error); }); } catch (err) { reject(error); } }); } }
routes.js
'use strict'; var express = require('express'); var kmsHelper = require('./encrypt'); var router = express.Router(); /* GET home page. */ router.get('/', function (req, res) { res.render('home.html'); }); router.post('/api/encrypt', function (req, res) { try { kmsHelper.encrypt(req.body.text).then(result => { res.send(result.toString()); }, err => { res.statusCode = 404; res.send(err); }); } catch (ex) { res.statusCode = 404; res.send(ex); } }); router.post('/api/decrypt', function (req, res) { try { kmsHelper.decrypt(req.body.text).then(result => { res.send(result.toString()); }, err => { res.statusCode = 404; res.send(err); }); } catch (ex) { res.statusCode = 404; res.send(ex); } }); module.exports = router;Happy Coding! 😊
0 comments:
Post a Comment