

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon SQS 密钥管理
<a name="sqs-key-management"></a>

Amazon SQS 与 AWS Key Management Service (KMS) 集成，用于管理服务器端加密 (SSE) 的 [KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)。有关 SSE 信息和密钥管理定义，请参阅[Amazon SQS 中的静态加密](sqs-server-side-encryption.md)。Amazon SQS 使用 KMS 密钥来验证和保护用于加密和解密消息的数据密钥。以下部分提供有关在 Amazon SQS 服务中使用 KMS 密钥和数据密钥的信息。

## 配置 AWS KMS 权限
<a name="sqs-what-permissions-for-sse"></a>

每个 KMS 密钥都必须有一个密钥政策。请注意，您无法修改 Amazon SQS 的 AWS 托管 KMS 密钥的密钥策略。此 KMS 密钥的政策包括该账户（获授权可使用 Amazon SQS）中所有主体使用加密队列的权限。

 Amazon SQS 根据来电者的 AWS 证书对来电者进行区分，无论他们使用的是不同的 AWS 账户、IAM 用户还是 IAM 角色。此外，具有不同作用策略范围的相同 IAM 角色将被视为不同的请求方。但是，在使用 IAM 角色会话时，仅更改 `RoleSessionName` 而保持相同的 IAM 角色和策略范围不会创建不同的请求方。因此，在指定 AWS KMS 关键策略主体时，请避免仅仅依赖`RoleSessionName`差异，因为这些会话将被视为同一个请求者。

或者，您可以在分配给主体的 IAM 策略中指定所需的权限，而这些主体可以创建和使用加密消息。有关更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[将 IAM 策略用于 AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/iam-policies.html)。

**注意**  
虽然您可以配置全局权限以向 Amazon SQS 发送和接收，但 AWS KMS 需要在 IAM 策略`Resource`部分中明确命名特定区域的 KMS 密钥的完整 ARN。

### 为 AWS 服务配置 KMS 权限
<a name="compatibility-with-aws-services"></a>

有几项 AWS 服务充当事件源，可以向 Amazon SQS 队列发送事件。要允许这些事件源使用加密队列，您必须创建客户托管的 KMS 密钥，并在密钥策略中添加权限以使用所需 AWS KMS 的 API 方法。执行以下步骤来配置权限。

**警告**  
请注意，更改用于加密 Amazon SQS 消息的 KMS 密钥时，使用旧 KMS 密钥加密的现有消息仍将使用该密钥进行加密。要解密这些消息，您必须保留旧的 KMS 密钥，并确保其密钥政策授予 Amazon SQS 执行 `kms:Decrypt` 和 `kms:GenerateDataKey` 的权限。在将加密新消息的密钥更新为新的 KMS 密钥后，请确保处理所有使用旧的 KMS 密钥加密的现有消息并将其从队列中删除，然后再删除或禁用旧的 KMS 密钥。

1. 创建客户托管的 KMS 密钥。有关更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[创建密钥](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)。

1. 要允许 AWS 服务事件源使用`kms:Decrypt`和 `kms:GenerateDataKey` API 方法，请在 KMS 密钥策略中添加以下语句。

------
#### [ JSON ]

****  

   ```
   {
      "Version":"2012-10-17",		 	 	 
         "Statement": [{
            "Effect": "Allow",
            "Principal": {
               "Service": "service.amazonaws.com"
            },
            "Action": [
               "kms:Decrypt",
               "kms:GenerateDataKey"
            ],
            "Resource": "*"
          }]
   }
   ```

------

   将上述示例中的“服务”替换为事件源的*服务名称*。事件源包括以下服务。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html)

1.  使用 KMS 密钥的 ARN [配置现有 SSE 队列](sqs-configure-sse-existing-queue.md)。

1. 向事件源提供加密队列的 ARN。

### 为制作者配置 AWS KMS 权限
<a name="send-to-encrypted-queue"></a>

当[数据密钥重用周期](#sqs-how-does-the-data-key-reuse-period-work)过期时，创建者下次调用 `SendMessage` 或 `SendMessageBatch` 时也会触发对 `kms:Decrypt` 和 `kms:GenerateDataKey` 的调用。对 `kms:Decrypt` 的调用是在使用新数据密钥之前验证它的完整性。因此，创建者必须具有 KMS 密钥的 `kms:Decrypt` 和 `kms:GenerateDataKey` 权限。

将以下语句添加到创建者的 IAM 策略中。请记住，为密钥资源和队列资源使用正确的 ARN 值。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:us-east-2:123456789012:key/111112222233333"
        },
        {
            "Effect": "Allow",
            "Action": [
                "sqs:SendMessage"
            ],
            "Resource": "arn:aws:sqs:*:123456789012:MyQueue"
        }
    ]
}
```

------

### 为消费者配置 AWS KMS 权限
<a name="receive-from-encrypted-queue"></a>

当数据密钥重用周期过期时，使用者下一次调用 `ReceiveMessage` 时也会触发对 `kms:Decrypt` 的调用，以便在使用新数据密钥之前验证它的完整性。因此，使用者必须对用于加密指定队列中消息的任何 KMS 密钥拥有 `kms:Decrypt` 权限。如果队列充当[死信队列](sqs-dead-letter-queues.md)，则使用者还必须具有用于加密源队列中消息的任何 KMS 密钥的 `kms:Decrypt` 权限。将以下语句添加到使用者的 IAM 策略中。请记住，为密钥资源和队列资源使用正确的 ARN 值。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": "arn:aws:kms:us-east-2:123456789012:key/111112222233333"
        },
        {
            "Effect": "Allow",
            "Action": [
                "sqs:ReceiveMessage"
            ],
            "Resource": "arn:aws:sqs:*:123456789012:MyQueue"
        }
    ]
}
```

------

### 在混淆副手保护的情况下配置 AWS KMS 权限
<a name="sqs-adding-confused-deputy-protection"></a>

当密钥政策语句中的主体为[AWS 服务主体](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-services)时，您可以使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) 或 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) 全局条件键以防止出现[混淆代理问题](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)。要使用这些条件键，请将值设置为要加密的资源的 Amazon 资源名称 (ARN)。如果您不知道资源的 ARN，请改用 `aws:SourceAccount`。

在此 KMS 密钥政策中，允许账户 `111122223333` 拥有的*服务*中的特定资源调用 KMS 进行 `Decrypt` 和 `GenerateDataKey` 操作，这些操作在 Amazon SQS 使用 SSE 期间发生。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "sqs.amazonaws.com"
            },
            "Action": [
                "kms:GenerateDataKey",
                "kms:Decrypt"
            ],
            "Resource": "*",
            "Condition": {
                "ArnEquals": {
                    "aws:SourceArn": [
                        "arn:aws:sqs:us-west-1:111122223333:resource"
                    ]
                }
            }
        }
    ]
}
```

------

使用启用 SSE 的 Amazon SQS 队列时，以下服务支持 `aws:SourceArn`：
+ Amazon SNS
+ Amazon S3
+ CloudWatch 活动
+ AWS Lambda
+ CodeBuild
+ Amazon Connect Customer Profiles
+ AWS Auto Scaling
+ Amazon Chime

## 了解数据密钥重用周期
<a name="sqs-how-does-the-data-key-reuse-period-work"></a>

[数据密钥重用周期](sqs-server-side-encryption.md#sqs-sse-key-terms)定义 Amazon SQS 重用相同数据密钥的最长持续时间。当数据密钥重用周期结束时，Amazon SQS 会生成一个新的数据密钥。请注意以下有关此重用周期的准则。
+ 较短的重复使用期可以提高安全性，但会导致更多的拨打电话 AWS KMS，这可能会产生超出免费套餐的费用。
+ 尽管用于加密和解密的数据密钥是单独缓存的，重用周期仍将应用于数据密钥的两个副本。
+ 当数据密钥重用期结束时，下一次调用`SendMessage`或`SendMessageBatch`通常会触发对 AWS KMS `GenerateDataKey`方法的调用以获取新的数据密钥。此外，接下来对`SendMessage`和的调用都`ReceiveMessage`将触发对的调用 AWS KMS `Decrypt`，以验证数据密钥的完整性，然后再使用它。
+ [委托人](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Principal)（AWS 账户 或用户）不共享数据密钥（由唯一委托人发送的消息始终会获得唯一的数据密钥）。因此，对的调用量 AWS KMS 是数据密钥重复使用期间使用的唯一主体数量的倍数。

## 估算成本 AWS KMS
<a name="sqs-estimate-kms-usage-costs"></a>

为了预测成本并更好地了解您的 AWS 账单，您可能需要了解 Amazon SQS 使用您的 KMS 密钥的频率。

**注意**  
尽管以下公式可让您很好地了解预计成本，但由于 Amazon SQS 的分布式特性，实际成本可能更高。

要计算*每个队列*的 API 请求数 (`R`)，请使用以下公式：

```
R = (B / D) * (2 * P + C)
```

`B` 是账单周期（以秒为单位）。

`D` 是[数据密钥重用周期](sqs-server-side-encryption.md#sqs-sse-key-terms)（以秒为单位）。

`P` 是发送到 Amazon SQS 队列的生成[主体](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Principal)的数量。

`C` 是从 Amazon SQS 队列接收的使用主体数量。

**重要**  
通常，创建主体产生的费用是使用主体的两倍。有关更多信息，请参阅 [了解数据密钥重用周期](#sqs-how-does-the-data-key-reuse-period-work)。  
如果创建者和使用者具有不同的用户，则费用会增加。

以下是一些示例计算。有关准确的定价信息，请参阅 [AWS Key Management Service 定价](https://aws.amazon.com/kms/pricing/)。

### 示例 1：计算 2 个委托人和 1 个队列的 AWS KMS API 调用次数
<a name="example-1-queue-2-principals"></a>

此示例假定：
+ 账单周期为 1 月 1 日 - 31 日（2678400 秒）。
+ 数据密钥重用周期设置为 5 分钟（300 秒）。
+ 有 1 个队列。
+ 有 1 个创建主体和 1 个使用主体。

```
(2,678,400 / 300) * (2 * 1 + 1) = 26,784
```

### 示例 2：计算多个生产者和使用者以及 2 个队列的 AWS KMS API 调用次数
<a name="example-2-queues-multiple-principals"></a>

此示例假定：
+ 账单周期为 2 月 1 日 - 28 日（2419200 秒）。
+ 数据密钥重用周期设置为 24 小时（86400 秒）。
+ 有 2 个队列。
+ 第一个队列有 3 个创建主体和 1 个使用主体。
+ 第二个队列有 5 个创建主体和 2 个使用主体。

```
(2,419,200 / 86,400 * (2 * 3 + 1)) + (2,419,200 / 86,400 * (2 * 5 + 2)) = 532
```

## AWS KMS 错误
<a name="sqs-sse-troubleshooting-errors"></a>

当您使用 Amazon SQS 和时 AWS KMS，可能会遇到错误。以下参考描述错误和可能的故障排除解决方案。
+ [常见 AWS KMS 错误](https://docs.aws.amazon.com/kms/latest/APIReference/CommonErrors.html)
+ [AWS KMS Decrypt 错误](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html#API_Decrypt_Errors)
+ [AWS KMS GenerateDataKey 错误](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html#API_GenerateDataKey_Errors)