无法将 IAM 秘密访问密钥转换为 SMTP 凭证

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

我正在尝试将秘密访问密钥转换为 SMTP 凭据。我按照 https://docs.aws.amazon.com/ses/latest/dg/smtp-credentials.html 中的说明进行操作,并从 https://gist.github.com/damusix/c12400ee0ccb7e56351619ae2b19a303 获取实现。但是,当我尝试发送电子邮件时,nodemailer 会抛出错误:

Error: Invalid login: 535 Authentication Credentials Invalid
。我错过了什么?

const region = "eu-central-1";

const date = "11111111";
const service = "ses";
const terminal = "aws4_request";
const message = "SendRawEmail";
const versionInBytes = [0x04];

function sign(key, msg: string) {
  return crypto
    .createHmac("sha256", Buffer.from(key.map((a) => a.charCodeAt(0))))
    .update(utf8.encode(msg))
    .digest("latin1")
    .split("");
}

export const generateSmtpPassword = (key: string) => {
  let signature = sign(utf8.encode("AWS4" + key).split(""), date);
  signature = sign(signature, region);
  signature = sign(signature, service);
  signature = sign(signature, terminal);
  signature = sign(signature, message);

  const signatureAndVersion = versionInBytes.slice(); //copy of array

  signature.forEach((a) => signatureAndVersion.push(a.charCodeAt(0)));

  const smtpPassword = Buffer.from(signatureAndVersion).toString("base64");

  return smtpPassword;
};
const id = generateId("project");

const iam = await getIAM();

const { User } = await iam.createUser({
  UserName: `project.${id}`,
});

if (!User?.UserName) throw new Error("Failed to create IAM user");

await iam.attachUserPolicy({
  UserName: User.UserName,
  PolicyArn: "arn:aws:iam::aws:policy/AmazonSESFullAccess",
});

const { AccessKey } = await iam.createAccessKey({
  UserName: User.UserName,
});

if (!AccessKey?.AccessKeyId || !AccessKey?.SecretAccessKey)
  throw new Error("AccessKeyId or SecretAccessKey is missing");

const smtpPassword = generateSmtpPassword(AccessKey.SecretAccessKey);

console.log(AccessKey);
//{
//  UserName: 'project.wLhJPIEKdSX3QIEB',
//  AccessKeyId: 'AKIA34AMCYCZNSLPIOGL',
//  Status: 'Active',
//  SecretAccessKey: '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',
//  CreateDate: 2024-10-25T08:41:51.000Z
//}

console.log(smtpPassword);
// BJFVirrONXceMVwlLwSiGPYw2NG1BCRmSlcslY5lg+SC

const transport = createTransport({
  host: "email-smtp.eu-central-1.amazonaws.com",
  port: 587,
  secure: false,
  auth: {
    user: AccessKey.AccessKeyId,
    pass: smtpPassword,
  },
});

await transport.sendMail({
  subject: ...,
  to: "***", // Verified address
  text: ...,
  from: "***", // Verified address
});
node.js amazon-web-services amazon-iam amazon-ses
1个回答
0
投票

首先我使用这个实现进行转换:https://gist.github.com/jesusgoku/533ba67ea218608c5a74a6d341d75189。但它不起作用的原因是 AWS 需要在其系统中传播用户(根据 ChatGPT)。所以我在发送电子邮件之前添加了延迟(大约 10 秒)。

await new Promise((resolve) => setTimeout(resolve, 10000))

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