Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encryption and Decryption file in s3 using Nodejs with AWS KMS

I am using AWS KMS to encrypt file to s3 bucket. I'm currently doing this using the AWS console, but I'd like to do this using Nodejs.

I just checked some of the things but I am not getting any clear idea about the encryption and decryption using nodejs for KMS.

like image 454
Team Avatar asked Feb 08 '17 07:02

Team


People also ask

How do I encrypt an AWS KMS file?

'aws kms encrypt' command is used for encrypting the data in the file. Specify the Key ARN or Key ID or Key Alias, input file path and region in the CLI command. Executing this command gives the encrypted file in base64 format. The base64 file is then decoded to get a binary encrypted file.

How do I encrypt decrypt data with AWS KMS on net?

You can also use the Decrypt operation to decrypt data encrypted outside of AWS KMS by the public key in an asymmetric KMS key. The KeyId parameter is not required when decrypting with symmetric encryption KMS keys. AWS KMS can get the KMS key that was used to encrypt the data from the metadata in the ciphertext blob.


2 Answers

You need to take a look at the AWS SDK for javascript. From the examples:

var AWS = require('aws-sdk');

var kms = new AWS.KMS({apiVersion: '2014-11-01'});
 
var params = {
  KeyId: "1234abcd-12ab-34cd-56ef-1234567890ab", // The identifier of the CMK to use for encryption. 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.
  Plaintext: <Binary String>// The data to encrypt.
 };

kms.encrypt(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
   /*
   data = {
    CiphertextBlob: <Binary String>, // The encrypted data (ciphertext).
    KeyId: "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"// The ARN of the CMK that was used to encrypt the data.
   }
   */
});

var params = {
  CiphertextBlob: <Binary String>// The encrypted data (ciphertext).
 };
 
kms.decrypt(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
   /*
   data = {
    KeyId: "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", // The Amazon Resource Name (ARN) of the CMK that was used to decrypt the data.
    Plaintext: <Binary String>// The decrypted (plaintext) data.
   }
   */
});

Here is the link for the aws-sdk package on NPM. Here is the link for the main AWS SDK for Javascript documentation page.

like image 59
Jeff Kilbride Avatar answered Sep 20 '22 11:09

Jeff Kilbride


Here is a complete example on how to encrypt and decrypt using AWS KMS:

// Imports
const AWS = require('aws-sdk');
const helper = require('./helper');

AWS.config.update({ region: 'eu-west-3' })

// Declare local variables
const kms = new AWS.KMS();

helper.getTextFile('./test.txt')
.then(buffer => encryptData(buffer))
.then(encryptedData => helper.saveBlobToFile(encryptedData))
.then(data => helper.getTextFile('./encryptedTxt.txt'))
.then(buffer => decryptData(buffer))
.then(plainText => helper.saveBlobToFile(plainText)) // plaintext
.catch(console.log);

function encryptData(buffer) {
    const params = {
        KeyId: 'your key id',
        Plaintext: buffer
    }
    return new Promise((resolve, reject) => {
        kms.encrypt(params, (err, data) => {
            if(err) reject(err);
            else resolve(data.CiphertextBlob);
        })
    })
}

function decryptData(buffer) {
    const params = {
        CiphertextBlob: buffer
    }
    return new Promise((resolve, reject) => {
        kms.decrypt(params, (err, data) => {
            if(err) reject(err);
            else resolve(data.Plaintext);
        })
    })
}

Helper methods are here:

const glob = require('glob')
const fs = require('fs')


function getTextFile(filePath) {
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, (err, data) => {
            if(err) reject(err);
            else {
                resolve(data); 
            }
        });
    })
}


function saveBlobToFile(blob) {
    var buffer = Buffer.from(blob, 'base64'); // decode
    return new Promise((resolve, reject) => {
        fs.writeFile('encryptedTxt.txt', buffer, (err) => {
            if(err) reject(err);
            else resolve('file saved correctly');
        })
    })
}

module.exports = {
    getTextFile,
    saveBlobToFile
}
like image 40
Peter Eskandar Avatar answered Sep 16 '22 11:09

Peter Eskandar