@aws-sdk/client-kms:解密数据时出错:TypeError:无法读取未定义的属性(读取“byteLength”)

问题描述 投票:0回答:1

我正在将 s3 和 kms 与 aws-sdk v3 nodejs 18 结合使用。

aws-sdk 版本,

├── @aws-sdk/[email protected]
└── @aws-sdk/[email protected]

S3 -> https://www.npmjs.com/package/@aws-sdk/client-s3 KMS -> https://www.npmjs.com/package/@aws-sdk/client-kms

我已使用此命令将文件上传到 s3 -

aws s3 cp config.json s3://lambda-config --sse aws:kms --sse-kms-key-id "my_kms_key_id"

现在我在 S3 存储桶(lambda-config)中有一个名为 -

config.json
的文件

现在我尝试从 S3 获取

config.json
文件并使用 Nodejs 18 中的 AWS-SDK v3 通过 KMS 进行解密,但出现以下错误

错误:

Error decrypting data: TypeError: Cannot read properties of undefined (reading 'byteLength')
at fromArrayBuffer (/Users/daswani/node_modules/@smithy/util-buffer-from/dist-cjs/index.js:6:60)
at toBase64 (/Users/daswani/node_modules/@smithy/util-base64/dist-cjs/toBase64.js:5:68)
at applyInstruction (/Users/daswani/node_modules/@smithy/smithy-client/dist-cjs/object-mapping.js:73:33)
at take (/Users/daswani/node_modules/@smithy/smithy-client/dist-cjs/object-mapping.js:44:9)
at se_DecryptRequest (/Users/daswani/node_modules/@aws-sdk/client-kms/dist-cjs/protocols/Aws_json1_1.js:3327:37)
at se_DecryptCommand (/Users/daswani/node_modules/@aws-sdk/client-kms/dist-cjs/protocols/Aws_json1_1.js:54:27)
at serialize (/Users/daswani/node_modules/@aws-sdk/client-kms/dist-cjs/commands/DecryptCommand.js:41:52)
at /Users/daswani/node_modules/@smithy/middleware-serde/dist-cjs/serializerMiddleware.js:12:27
at /Users/daswani/node_modules/@smithy/middleware-endpoint/dist-cjs/endpointMiddleware.js:20:16

上述错误的代码示例

const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
const { KMSClient, DecryptCommand } = require("@aws-sdk/client-kms");
const fs = require('fs');

const s3Client = new S3Client({ region: 'ap-south-1' }); 
const kmsClient = new KMSClient({ region: 'ap-south-1' }); 

const s3Bucket = 'lambda-config';
const s3ObjectKey = 'config.json';

const keyId = 'my_kms_key_id';

async function fetchFileFromS3(bucket, objectKey) {
  const getObjectParams = {
    Bucket: bucket,
    Key: objectKey
  };

  try {
    const getObjectCommand = new GetObjectCommand(getObjectParams);
    const { Body } = await s3Client.send(getObjectCommand);
    return Body;
  } catch (error) {
    console.error('Error fetching file from S3:', error);
    throw error;
  }
}

async function decryptData(encryptedData) {
  const decryptParams = {
    CiphertextBlob: encryptedData
  };

  try {
    const decryptCommand = new DecryptCommand(decryptParams);
    const { Plaintext } = await kmsClient.send(decryptCommand);
    return Plaintext.toString('base64');
  } catch (error) {
    console.error('Error decrypting data:', error);
    throw error;
  }
}

const outputFilePath = 'decrypted.txt';

fetchFileFromS3(s3Bucket, s3ObjectKey)
  .then(async (fileData) => {
    const decryptedData = await decryptData(fileData);

    fs.writeFileSync(outputFilePath, decryptedData, 'base64');
    console.log('Decrypted data written to', outputFilePath);
  })
  .catch(error => {
    console.error('An error occurred:', error);
  });

我尝试按照nodejs 16 aws-sdk v2转换此代码,我能够使用v2解密文件内容,但使用aws-sdk v3时出现错误

node.js aws-lambda aws-sdk amazon-kms
1个回答
0
投票

我也偶然发现了这一点。这是一个有效的代码示例:

基本上你需要将

encryptedData
包裹成
Buffer.from(encryptedData, 'base64')

import { DecryptCommand, EncryptCommand, KMSClient } from '@aws-sdk/client-kms';

export default class KmsEncryption {
  constructor(keyId, region, endpoint = null) {
    super();
    this.keyId = keyId;
    this.kms = new KMSClient({
      region,
      endpoint,
    });
  }

  async encrypt(plainText) {
    const response = await this.kms.send(
      new EncryptCommand({
        KeyId: this.keyId,
        Plaintext: Buffer.from(plainText),
      }),
    );

    return Buffer.from(response.CiphertextBlob)
      .toString('base64');
  }

  async decrypt(encryptedTextBase64) {
    const response = await this.kms.send(
      new DecryptCommand({
        KeyId: this.keyId,
        CiphertextBlob: Buffer.from(encryptedTextBase64, 'base64'),
      }),
    );

    return Buffer.from(response.Plaintext).toString('ascii');
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.