Skip to content

Instantly share code, notes, and snippets.

@JoeShi
Created October 30, 2018 16:04
Show Gist options
  • Save JoeShi/344fb5c92662759aaca6bd146d53efcd to your computer and use it in GitHub Desktop.
Save JoeShi/344fb5c92662759aaca6bd146d53efcd to your computer and use it in GitHub Desktop.
KMS demo using node.js
/**
* This is a demo of KMS.
*
* This demo includes the following two features:
* 1. encrypt and decrypt using CMK (Customer Master Key)
* 2. encrypt and decrypt using data key (Envelope encryption using AWS KMS)
*
*/
'use strict';
const AWS = require('aws-sdk');
const crypto = require('crypto');
const kmsClient = new AWS.KMS({
region: 'us-west-2'
});
const KeyId = 'arn:aws:kms:us-west-2:xxxxxxx:key/xxxxxxxx'; // replace with your Customer Master Key ARN
const KeySpec = 'AES_256';
const data = 'this is a plain text data';
/**
* Encrypt the data using AES-256
* @param key
* @param buffer
* @returns {void|*|Promise<any>}
*/
function encryptAES(key, buffer) {
const iv = new Buffer('00000000000000000000000000000000', 'hex');
const encryptor = crypto.createCipheriv('AES-256-CBC', key, iv);
encryptor.write(buffer);
encryptor.end();
return encryptor.read();
}
/**
* Decrypt the data using AES-256
* @param key
* @param buffer
* @returns {void|*|Promise<any>}
*/
function decryptAES(key, buffer) {
const iv = new Buffer('00000000000000000000000000000000', 'hex');
const encryptor = crypto.createDecipheriv('AES-256-CBC', key, iv);
encryptor.write(buffer);
encryptor.end();
return encryptor.read();
}
async function encryptWithDataKey() {
const { CiphertextBlob, Plaintext } = await kmsClient.generateDataKey({ KeyId, KeySpec }).promise();
const testString = new Buffer(data, 'utf-8');
const encryptedData = await encryptAES(Plaintext, testString);
const decryptedData = await decryptAES(Plaintext, encryptedData);
console.log('2:', decryptedData.toString()); // should print data content
return { CiphertextBlob, encryptedData }
}
async function decryptWithDataKey(encryptedKey, encryptedData) {
// decrypt the data key
const {KeyId, Plaintext} = await kmsClient.decrypt({ CiphertextBlob: encryptedKey }).promise();
const decryptedData = await decryptAES(Plaintext, encryptedData);
console.log('3:', decryptedData.toString()); // should print data content
return decryptedData
}
async function encryptWithCMK() {
const { CiphertextBlob, keyId} = await kmsClient.encrypt({ KeyId, Plaintext: new Buffer(data, 'utf-8') }).promise();
return CiphertextBlob
}
async function decryptWithCMK(CiphertextBlob) {
const {KeyId, Plaintext} = await kmsClient.decrypt({ CiphertextBlob: CiphertextBlob }).promise();
console.log('1:', Plaintext.toString()) // should print the data
}
encryptWithCMK()
.then(CiphertextBlob => {
return decryptWithCMK(CiphertextBlob)
}).then(() => {
return encryptWithDataKey()
}).then(data => {
return decryptWithDataKey(data.CiphertextBlob, data.encryptedData)
}).then(() => {
console.log('done')
}).catch(err => {
console.error(err)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment