

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

# 管理 Amazon SNS 加密密钥和成本
<a name="sns-key-management"></a>

以下部分提供了有关使用 AWS Key Management Service (AWS KMS) 中托管的密钥的信息。

**注意**  
Amazon SNS 仅支持对称加密 KMS 密钥。您不能使用任何其他类型的 KMS 密钥来加密您的服务资源。有关确定 KMS 密钥是否为对称加密密钥的帮助，请参阅[识别非对称 KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/find-symm-asymm.html)。

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

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

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

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

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

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

`D` 是数据密钥重用周期（以秒为单位，Amazon SNS 重用数据密钥长达 5 分钟）。

`P` 是发送到 Amazon SNS 主题的发布[委托人](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Principal)的数量。

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

### 示例 1：计算 1 个发布者和 1 个主题的 AWS KMS API 调用次数
<a name="example-1-topic-1-publisher"></a>

此示例假定：
+ 账单周期为 1 月 1 日 - 31 日（2678400 秒）。
+ 数据密钥重用周期为 5 分钟（300 秒）。
+ 提供了 1 个主题。
+ 提供了 1 个发布委托人。

```
2,678,400 / 300 * (2 * 1) = 17,856
```

### 示例 2：计算多个发布商和 2 个主题的 AWS KMS API 调用次数
<a name="example-2-topics-multiple-publishers"></a>

此示例假定：
+ 账单周期为 2 月 1 日 - 28 日（2419200 秒）。
+ 数据密钥重用周期为 5 分钟（300 秒）。
+ 提供了 2 个主题。
+ 第一个主题具有 3 个发布委托人。
+ 第二个主题具有 5 个发布委托人。

```
(2,419,200 / 300 * (2 * 3)) + (2,419,200 / 300 * (2 * 5)) = 129,024
```

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

在使用 SSE 之前，必须将 AWS KMS key 策略配置为允许对主题进行加密以及对消息进行加密和解密。有关 AWS KMS 权限的示例和更多信息，请参阅 *AWS Key Management Service 开发人员指南*中的 [AWS KMS API 权限：操作和资源参考](https://docs.aws.amazon.com/kms/latest/developerguide/kms-api-permissions-reference.html)。有关如何使用服务器端加密设置 Amazon SNS 主题的详细信息，请参阅[附加信息](sns-enable-encryption-for-topic.md#set-up-topic-with-sse)。

**注意**  
您也可以使用 IAM policy 来管理对称加密 KMS 密钥的权限。有关更多信息，请参阅[将 IAM 策略与一起使用 AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/iam-policies.html)。  
虽然您可以配置向 Amazon SNS 发送和接收的全局权限，但 AWS KMS 需要在 IAM 策略`Resource`部分 KMSs 中明确命名特定区域的完整 ARN。

您还必须确保的密钥策略 AWS KMS key 允许必要的权限。为此，请将在 Amazon SNS 中创建和使用加密消息的委托人指定为 CMK 密钥策略中的用户。

或者，您可以在分配给在 Amazon SNS 中发布和订阅以接收加密消息的委托人的 IAM 策略中指定所需的 AWS KMS 操作和 KMS ARN。有关更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[管理对 AWS KMS的访问](https://docs.aws.amazon.com/kms/latest/developerguide/control-access-overview.html#managing-access)。

如果为您的 Amazon SNS 主题选择了客户自主管理型密钥，并且您正在使用别名通过 IAM policy 或带有条件密钥 `kms:ResourceAliases` 的 KMS 密钥策略来控制 KMS 密钥的访问权限，请确保所选的客户自主管理型密钥也关联了别名。有关使用别名控制 KMS 密钥的访问权限的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[使用别名控制 KMS 密钥的访问权限](https://docs.aws.amazon.com/kms/latest/developerguide/alias-authorization.html)。

### 允许用户使用 SSE 将消息发送到主题
<a name="send-to-encrypted-topic"></a>

发布者必须具有 AWS KMS key的 `kms:GenerateDataKey*` 和 `kms:Decrypt` 权限。

```
{
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "kms:GenerateDataKey*",
      "kms:Decrypt"
    ],
    "Resource": "arn:aws:kms:us-east-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"
  }, {
    "Effect": "Allow",
    "Action": [
      "sns:Publish"
    ],
    "Resource": "arn:aws:sns:*:123456789012:MyTopic"
  }]
}
```

### 启用来自 AWS 服务的事件源和加密主题之间的兼容性
<a name="compatibility-with-aws-services"></a>

一些 AWS 服务会向 Amazon SNS 主题发布事件。要允许这些事件源使用加密主题，您必须执行以下步骤。

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

1. 要允许 AWS 服务拥有`kms:GenerateDataKey*`和`kms:Decrypt`权限，请在 KMS 策略中添加以下语句。

   ```
   {
     "Statement": [{
       "Effect": "Allow",
       "Principal": {
         "Service": "service.amazonaws.com"
       },
       "Action": [
         "kms:GenerateDataKey*",
         "kms:Decrypt"
       ],
       "Resource": "*"
     }]
   }
   ```    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/sns-key-management.html)
**注意**  
某些 Amazon SNS 事件源要求您在策略中提供 IAM 角色（而不是服务委托人）： AWS KMS key   
[Amazon EC2 Auto Scaling](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ASGettingNotifications.html)
[Amazon Elastic Transcoder](https://docs.aws.amazon.com/elastictranscoder/latest/developerguide/notifications.html)
[AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/approvals.html#approvals-configuration-options)
[AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/notifications-for-AWS-Config.html)
[AWS Elastic Beanstalk](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.sns.html)
[AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sns-rule.html)
[EC2 Image Builder](https://docs.aws.amazon.com/imagebuilder/latest/userguide/ibhow-integrations.html#integ-sns-encrypted)

1. 将 `aws:SourceAccount` 和 `aws:SourceArn` 条件键添加到 KMS 资源策略，以进一步保护 KMS 密钥免受[混淆代理](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)攻击。有关每种案例的具体详细信息，请参阅上述特定于服务的文档列表。
**重要**  
 EventBridge-to-encrypted主题不支持在`aws:SourceAccount` AWS KMS 策略中添加`aws:SourceArn`、和`aws:SourceOrgID`。

   ```
   {
     "Effect": "Allow",
     "Principal": {
       "Service": "service.amazonaws.com"
     },
     "Action": [
       "kms:GenerateDataKey*",
       "kms:Decrypt"
     ],
     "Resource": "*",
     "Condition": {
       "StringEquals": {
         "aws:SourceAccount": "customer-account-id"
       },
       "ArnLike": {
         "aws:SourceArn": "arn:aws:service:region:customer-account-id:resource-type:customer-resource-id"
       }
     }
   }
   ```

1. 使用 KMS [为您的主题启用 SSE](sns-enable-encryption-for-topic.md)。

1. 向事件源提供加密主题的 ARN。

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

当您使用 Amazon SNS 和时 AWS KMS，可能会遇到错误。以下列表描述了这些错误和可能的故障排除解决方案。

**KMSAccessDeniedException**  
密文引用了不存在的或您无权访问的密钥。  
HTTP 状态代码：400

**KMSDisabled例外**  
由于指定的 KMS 未启用，请求被拒绝。  
HTTP 状态代码：400

**KMSInvalidStateException**  
由于指定资源的状态对此请求无效，请求被拒绝。有关更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的 [AWS KMS keys的密钥状态](https://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)。  
HTTP 状态代码：400

**KMSNotFoundException**  
由于找不到指定的实体或资源，请求被拒绝。  
HTTP 状态代码：400

**KMSOptInRequired**  
 AWS 访问密钥 ID 需要订阅该服务。  
HTTP 状态代码：403

**KMSThrottling例外**  
由于请求限制而导致请求被拒绝。有关节流的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[限额](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html#requests-per-second)。  
HTTP 状态代码：400