节点:AWS KMS 从内存中擦除 public 密钥

Node: AWS KMS erasing public key from memory

来自 KMS 操作文档 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.

此代码是否足以确保明文密钥在使用完毕后已从内存中删除。

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");
}

假设 aws sdk 不会 leak/copy 将密钥放入内存的其他部分是否安全,并且与内置加密库的 createCipheriv 函数相同,因此只是覆盖Plaintext 带零的缓冲区应该足以从内存中擦除密钥?

这就是适用于 JavaScript 的 AWS 加密 SDK [1] 的作用。 事实上,如果 Encryption SDK 提供了您需要的功能, 我建议只使用它。

aws-sdk 将此值视为敏感值 并在 Node.js[2] 中创建一个独立的缓冲区。 这意味着明文密钥作用于此函数 只要它不分享, 没有其他副本,也没有人可以访问。 (通常的 "no bad people have root access to you server" 适用)

跟踪节点 [3]..[4] 中的调用 createCipheriv 它提供了对 openSSL 密钥的引用,而不是副本。

[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