Search code examples
node.jsamazon-web-servicesamazon-kms

How to encrypt and decrypt a string using AWS KMS?


I am trying to use AWS KMS to encrypt and decrypt a simple string,
I am using the AWS Javascript SDK to do so,
I am able to encrypt and somewhat decrypt the string as there are no errors,
But the output of the KMS decrypt method, does not result in my original string which I was trying to encrypt.

Here is my working code -

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

AWS.config.update({region:'us-east-1'});
var kms = new AWS.KMS({apiVersion: '2014-11-01'});

let test = async () => {

    try {
        let data = `test`;

        var encryptionParams = {
            KeyId: "someKMSKeyId",
            Plaintext: data
        };

        let kmsEncrypt = util.promisify(kms.encrypt).bind(kms);
        let encryptedData = await kmsEncrypt(encryptionParams);

        //encryptedData contained 2 parts, CiphertextBlob and KeyId
        console.log('encryptedData => \n', encryptedData);
        console.log('\nencryptedData.CiphertextBlob => \n', encryptedData.CiphertextBlob);
        console.log('\nencryptedData.KeyId => \n', encryptedData.KeyId);

        var decryptionParams = {
            CiphertextBlob : encryptedData.CiphertextBlob
        };

        let kmsDecrypt = util.promisify(kms.decrypt).bind(kms);
        let decryptedData = await kmsDecrypt(decryptionParams);

        //ndecryptedData contained 2 parts, Plaintext and KeyId
        console.log('\ndecryptedData => \n', decryptedData);
        console.log('\ndecryptedData.Plaintext => \n', decryptedData.Plaintext);
        console.log('\ndecryptedData.KeyId => \n', decryptedData.KeyId);
    } catch (error) {
        console.log('\nerror => \n',error);
    }
}

test();

I am expecting the output of decryptedData.Plaintextto be test,
But the output is something like - <Buffer 74 65 73 74>,
What am I doing wrong here?

Reference -
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/KMS.html#endpoint-property


Solution

  • Thanks to kdgregory's hint, I was able to resolve this by decoding the PlainText into a String using base64,
    Following is the final working code for encryption and decryption using AWS KMS -

    var AWS = require('aws-sdk');
    const util = require('util');
    
    AWS.config.update({region:'us-east-1'});
    var kms = new AWS.KMS({apiVersion: '2014-11-01'});
    
    let test = async () => {
    
        try {
            let data = 'test';
    
            var encryptionParams = {
                KeyId: "kmsKeyId",
                Plaintext: data
            };
    
            let kmsEncrypt = util.promisify(kms.encrypt).bind(kms);
            let encryptedData = await kmsEncrypt(encryptionParams);
    
            //encryptedData contained 2 parts, CiphertextBlob and KeyId
            console.log('encryptedData => \n', encryptedData);
            console.log('\nencryptedData.CiphertextBlob => \n', encryptedData.CiphertextBlob);
            console.log('\nencryptedData.KeyId => \n', encryptedData.KeyId);
    
            let buff = Buffer.from(encryptedData.CiphertextBlob);
            let encryptedBase64data = buff.toString('base64');
            console.log("\nencryptedBase64data => \n", encryptedBase64data);
    
            var decryptionParams = {
                CiphertextBlob : encryptedData.CiphertextBlob
            };
    
            let kmsDecrypt = util.promisify(kms.decrypt).bind(kms);
            let decryptedData = await kmsDecrypt(decryptionParams);
    
            //ndecryptedData contained 2 parts, Plaintext and KeyId
            console.log('\ndecryptedData => \n', decryptedData);
            console.log('\ndecryptedData.Plaintext => \n', decryptedData.Plaintext);
            console.log('\ndecryptedData.KeyId => \n', decryptedData.KeyId);
    
            let buff2 = Buffer.from(decryptedData.Plaintext, 'base64');  
            let originalText = buff2.toString('ascii');
            console.log('\noriginalText => \n', originalText);
        } catch (error) {
            console.log('\nerror => \n',error);
        }
    }
    
    test();