从 S3 到 SQS 的加密存储桶通知

Nic*_*Nic 4 amazon-s3 amazon-sqs amazon-web-services aws-kms

如何将 S3 存储桶通知设置到 SQS 中的队列,其中 KMS 用于存储桶和队列?

  • 我在 S3 中有一个存储桶,其中的内容使用 AWS 托管密钥(aws/s3默认密钥)加密。
  • 我在 SQS 中有一个队列,其中启用了 SSE(服务器端加密),但使用的是 CMK(客户管理的密钥)。

当我进入 S3 Web 控制台并尝试在我的存储桶上添加一个通知事件以发送到我在 SQS 中的队列时,我看到以下错误消息:

无法验证以下目标配置。无法使用 KMS 加密到 SSE 队列的消息。(arn:aws:sqs:ca-central-1: ... : ...)

我已经尝试配置我的 KMS 密钥策略以授予 S3 服务帐户所需的权限。

        {
            "Sid": "Let S3 encrypt messages so that bucket notifications can be encrypted",
            "Effect": "Allow",
            "Principal": {
                "Service": "s3.amazonaws.com"
            },
            "Action": [
                "kms:GenerateDataKey",
                "kms:Encrypt"
            ],
            "Resource": "*"
        },
Run Code Online (Sandbox Code Playgroud)

我需要做什么才能允许将存储桶通知发送到加密队列?

jel*_*csc 5

根据文档,第二个操作应该是kms:Decrypt而不是kms:Encrypt.

至于为什么kms:Decrypt需要,这有点违反直觉。您可能会想,由于 SQS 队列是加密的,所以当 S3 服务调用SendMessage API 时,它需要kms:Encrypt权限来确保消息可以被KMS 服务加密,对吗?不完全是,原因如下:

  1. 消息直接由主密钥 (CMK) 加密。相反,它使用信封加密,数据由数据密钥加密。为什么?因为对称 CMK 使用Encrypt API可以加密的最大数据大小为 4096 字节,而 SQS 服务支持的消息大小可以远大于 4KB。因此,kms:Encrypt必要的,而是kms:GenerateDataKey需要产生被用来加密SQS消息的数据项。

  2. 此 AWS 文档的“为生产者配置 KMS 权限”部分中,解释了为什么kms:Decrypt需要。

调用kms:Decrypt是在使用新数据密钥之前验证其完整性。

非常清楚,GenerateDataKey API返回明文数据密钥数据密钥的加密副本。明文数据密钥用于加密 SQS 消息,加密后的数据密钥将与消息一起存储在队列中。验证加密的数据密钥确实是明文数据密钥的密文的唯一方法是服务需要具有kms:Decrypt解密密文的权限,并确保输出与 GenerateDataKey 中返回的明文数据密钥完全相同API 响应。