You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
注册

如何为@aws-crypto/client-node配置代理以访问AWS服务

问题描述

我们的容器运行在需要通过代理访问AWS服务的环境中。我已通过AWS.config.update({ httpOptions: { agent } })设置代理,但该配置在使用AWS Encryption SDK进行加密和解密时并未生效。

已尝试的操作

  • 通过AWS.config.update()传递代理配置
  • 使用带代理的https.Agent并将其赋值给AWS.config.httpOptions.agent

代码示例

const {  buildClient,
    KmsKeyringNode,
    CommitmentPolicy,
    getClient, KMS} = require('@aws-crypto/client-node');
const { encrypt, decrypt } = buildClient(
    CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)
const AWS = require('aws-sdk');

AWS.config.update({
    region: 'me-central-1',
});

// Define the KMS key ARN (or Key ID)
const keyArn = 'arn:aws:kms:me-central-1:************:alias/GNS-ENC';
const keyring = new KmsKeyringNode({
  generatorKeyId: keyArn,  // Use the Key ARN or Key ID to initialize the Keyring
  keyIds:['arn:aws:kms:me-central-1:************:key/********************'],
  clientProvider:getClient(KMS,{
    credentials:{
      accessKeyId: 'AKIA****************',
      secretAccessKey:'********************************'
    }
  })
});
// Function to encrypt data
async function encryptData(plaintext) {
  try {
    // Encrypt the plaintext using the keyring
    const { result } = await encrypt(keyring, plaintext)

    // Convert the ciphertext to base64 and log
    console.log('Encrypted data (base64):', Buffer.from(result, 'utf-8').toString('base64'));
    return result; // Return the ciphertext to use for decryption
  } catch (err) {
    console.error('Encryption failed:', err);
  }
}

// Function to decrypt data
async function decryptData(encryptedData) {
  try {
    // Decrypt the ciphertext
    const ciphertext = Buffer.from(encryptedData, 'base64');  
    const { plaintext } = await decrypt(keyring, ciphertext);

    // Convert the decrypted data back to string and log
    const decryptedData = plaintext.toString('utf-8');
    console.log('Decrypted data:', decryptedData);
    return decryptedData;
  } catch (err) {
    console.error('Decryption failed:', err);
  }
}

// Main function to run the encryption and decryption flow
async function testEncryptionDecryption() {
  const plaintext = 'Hello, AWS Encryption SDK with KMSKeyringNode!';

  // Step 1: Encrypt the data
  const encryptedData = await encryptData(plaintext);

  // Step 2: Decrypt the data
  if (encryptedData) {
    await decryptData(encryptedData);
  }
}

// Run the test
testEncryptionDecryption();

解决方案

问题核心是AWS Encryption SDK通过getClient创建的KMS客户端不会自动继承全局AWS.config的代理配置,必须在创建该客户端时显式传入代理参数。

步骤1:初始化带代理的Agent

根据代理类型(HTTP/HTTPS)创建对应的Agent实例:

const https = require('https');
// 若为HTTP代理,替换为 require('http')
const proxyAgent = new https.Agent({
  host: '你的代理地址',
  port: 你的代理端口,
  // 代理需要认证时添加以下内容
  // auth: '用户名:密码'
});

步骤2:为KMS客户端配置代理

修改getClient的配置项,将代理Agent加入httpOptions

const keyring = new KmsKeyringNode({
  generatorKeyId: keyArn,
  keyIds:['arn:aws:kms:me-central-1:************:key/********************'],
  clientProvider:getClient(KMS,{
    credentials:{
      accessKeyId: 'AKIA****************',
      secretAccessKey:'********************************'
    },
    // 新增代理配置
    httpOptions: {
      agent: proxyAgent
    },
    region: 'me-central-1'
  })
});

完整修改后的代码

const {  buildClient,
    KmsKeyringNode,
    CommitmentPolicy,
    getClient, KMS} = require('@aws-crypto/client-node');
const { encrypt, decrypt } = buildClient(
    CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)
const AWS = require('aws-sdk');
const https = require('https');

// 初始化代理Agent
const proxyAgent = new https.Agent({
  host: 'proxy.example.com', // 替换为你的代理地址
  port: 8080, // 替换为你的代理端口
  // auth: 'user:pass' // 代理需要认证时取消注释
});

// 全局AWS配置(代理配置不会被Encryption SDK的KMS客户端读取,可保留其他配置)
AWS.config.update({
    region: 'me-central-1',
});

// Define the KMS key ARN (or Key ID)
const keyArn = 'arn:aws:kms:me-central-1:************:alias/GNS-ENC';
const keyring = new KmsKeyringNode({
  generatorKeyId: keyArn,  // Use the Key ARN or Key ID to initialize the Keyring
  keyIds:['arn:aws:kms:me-central-1:************:key/********************'],
  clientProvider:getClient(KMS,{
    credentials:{
      accessKeyId: 'AKIA****************',
      secretAccessKey:'********************************'
    },
    // 为KMS客户端单独配置代理
    httpOptions: {
      agent: proxyAgent
    },
    region: 'me-central-1'
  })
});
// Function to encrypt data
async function encryptData(plaintext) {
  try {
    // Encrypt the plaintext using the keyring
    const { result } = await encrypt(keyring, plaintext)

    // Convert the ciphertext to base64 and log
    console.log('Encrypted data (base64):', Buffer.from(result, 'utf-8').toString('base64'));
    return result; // Return the ciphertext to use for decryption
  } catch (err) {
    console.error('Encryption failed:', err);
  }
}

// Function to decrypt data
async function decryptData(encryptedData) {
  try {
    // Decrypt the ciphertext
    const ciphertext = Buffer.from(encryptedData, 'base64');  
    const { plaintext } = await decrypt(keyring, ciphertext);

    // Convert the decrypted data back to string and log
    const decryptedData = plaintext.toString('utf-8');
    console.log('Decrypted data:', decryptedData);
    return decryptedData;
  } catch (err) {
    console.error('Decryption failed:', err);
  }
}

// Main function to run the encryption and decryption flow
async function testEncryptionDecryption() {
  const plaintext = 'Hello, AWS Encryption SDK with KMSKeyringNode!';

  // Step 1: Encrypt the data
  const encryptedData = await encryptData(plaintext);

  // Step 2: Decrypt the data
  if (encryptedData) {
    await decryptData(encryptedData);
  }
}

// Run the test
testEncryptionDecryption();

关键说明

  • getClient创建的KMS客户端是独立实例,不会读取全局AWS.config中的httpOptions,必须显式传入代理参数。
  • 代理为HTTP类型时,将https.Agent替换为http.Agent即可。

内容的提问来源于stack exchange,提问作者Aravind Piratla

火山引擎 最新活动