Greg Hornby
Greg Hornby

Reputation: 7798

Node: AWS KMS erasing public key from memory

From the docs for the KMS operation GenerateDataKey https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html

We recommend that you use the following pattern to encrypt data locally in your application:

Use the GenerateDataKey operation to get a data encryption key.

Use the plaintext data key (returned in the Plaintext field of the response) to encrypt data locally, then erase the plaintext data key from memory.

Would this code be sufficient to ensure that the plaintext key has been erased from memory when done using it.

const aws = require("aws-sdk");
const kms = new aws.KMS({...config});

(async () => {

    /** {Plaintext: Buffer, CiphertextBlob: Buffer} **/
    let dataKey = await kms.generateDataKey({...options}).promise();

    let encryptedString = MyEncryptionFunction(dataKey.Plaintext, "Hello World");

    dataKey.Plaintext.fill(0); //overwrite the buffer with zeroes to erase from memory;
})();

function MyEncryptionFunction(key, dataString) {
    let iv = crypto.randomBytes(16);
    let cipher = crypto.createCipheriv("aes256", key, iv);
    return cipher.update(dataString, "utf8", "hex") + cipher.final("hex");
}

Is it safe to assume the aws sdk doesn't leak/copy the key into other parts of the memory, and the same with the createCipheriv function of the builtin crypto library and so just overwriting the Plaintext buffer with zeroes should sufficiently wipe the key from memory?

Upvotes: 0

Views: 437

Answers (1)

ryan
ryan

Reputation: 141

This is what the AWS Encryption SDK for JavaScript does [1]. In fact, if the Encryption SDK provides the features you need, I would recommend just using that.

The aws-sdk treats this value as sensitive and creates an isolated Buffer in Node.js[2]. This means that the plaintext key scoped to this function and as long as it does not share it, there are no other copies, and no one has access. (The usual "no bad people have root access to you server" applies)

Tracing the call createCipheriv in node [3]..[4] it hands a reference of the key to openSSL, not a copy.

[1] https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/material-management/src/cryptographic_material.ts#L343

[2] https://github.com/aws/aws-sdk-js/pull/2622/files

[3] https://github.com/nodejs/node/blob/master/lib/crypto.js#L114

[4] https://github.com/nodejs/node/blob/master/src/node_crypto.cc#L4099

Upvotes: 2

Related Questions