如何为@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




