Advertisements
RSS

Using AWS Key Management (KMS) to encrypt and decrypt in AWS Lambda (NodeJS)

05 Nov

AWS Key Management (KMS) is a fully managed service that makes it easy to create and control encryption keys on AWS which can then be utilised to encrypt and decrypt data in a safe manner. The service leverages Hardware Security Modules (HSM) under the hood which in return guarantees security and integrity of the generated keys.

You can enable AWS KMS to store your data-at-rest on many AWS storage solutions (like DynamoDB and EBS). However in our Lambda functions we would like to encrypt (and decrypt) certain values on runtime. So we needed some code to encrypt and decrypt. Took me some while to figure it out, so here it is.

Here is the function to encrypt any string against the AWS KMS Key. You can create a KMS Key through AWS IAM in the console or (much better) AWS CloudFormation.

const kmsClient = new AWS.KMS({region: 'eu-west-1'});

/**
 * Encrypt
 */
async function encryptString(text: string): Promise<string> {

    const paramsEncrypt = {
        KeyId: 'arn:aws:kms:eu-west-1:........',
        Plaintext: new Buffer(text)
    };

    const encryptResult = await kmsClient.encrypt(paramsEncrypt).promise();
    // The encrypted plaintext. When you use the HTTP API or the AWS CLI, the value is Base64-encoded. Otherwise, it is not encoded.
    if (Buffer.isBuffer(encryptResult.CiphertextBlob)) {
        return Buffer.from(encryptResult.CiphertextBlob).toString('base64');
    } else {
        throw new Error('Mayday Mayday');
    }
}

And we can use the result (an encrypted string) to store it in DynamoDB, Aurora or send it wherever we want. So in the end we would like to decrypt it as well. So …

/**
 * Decrypt
 */
async function decryptEncodedstring(encoded: string): Promise<string> {

    const paramsDecrypt: AWS.KMS.DecryptRequest = {
        CiphertextBlob: Buffer.from(encoded, 'base64')
    };

    const decryptResult = await kmsClient.decrypt(paramsDecrypt).promise();
    if (Buffer.isBuffer(decryptResult.Plaintext)) {
        return Buffer.from(decryptResult.Plaintext).toString();
    } else {
        throw new Error('We have a problem');
    }
}

Hope it helps!

References

  • Example code including test function available in my Github as well

 

Advertisements
 
Leave a comment

Posted by on 05-11-2018 in AWS

 

Tags: , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

 
%d bloggers like this: