

# 使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本
<a name="bucket-key"></a>

Amazon S3 存储桶密钥降低了具有 AWS Key Management Service（AWS KMS）密钥的 Amazon S3 服务器端加密（SSE-KMS）的成本。使用 SSE-KMS 的存储桶级别密钥可以通过减少从 Amazon S3 到 AWS KMS 的请求流量，从而使您可以将 AWS KMS 请求成本最高降低 99%。只需在 AWS 管理控制台中单击几下，无需对客户端应用程序进行任何更改，您就可以将存储桶配置为使用 S3 存储桶密钥对新对象进行 SSE-KMS 加密。

**注意**  
使用 AWS Key Management Service（AWS KMS）密钥的双层服务器端加密（DSSE-KMS）不支持 S3 存储桶密钥。

## SSE-KMS 的 S3 存储桶密钥
<a name="bucket-key-overview"></a>

访问使用 SSE-KMS 加密的数百万或数十亿个对象的工作负载可以生成大量到 AWS KMS 的请求。当您在没有 S3 存储桶密钥的情况下使用 SSE-KMS 保护数据时，Amazon S3 会为每个对象使用单独的 AWS KMS [数据密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys)。在这种情况下，每次对 KMS 加密的对象发出请求时，Amazon S3 都会调用 AWS KMS。有关 SSE-KMS 工作原理的信息，请参阅 [使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）](UsingKMSEncryption.md)。

当您将存储桶配置为使用 S3 存储桶密钥进行 SSE-KMS 加密时，AWS 会从 AWS KMS 生成生存期较短的存储桶级密钥，然后暂时将其保留在 S3 中。此存储桶级密钥将在新对象的生命周期中为其创建数据密钥。S3 存储桶密钥在 Amazon S3 内限时使用，从而减少了 S3 向 AWS KMS 发出请求以完成加密操作的需求。这样可以减少从 S3 到 AWS KMS 的流量，使您能够在 Amazon S3 中访问 AWS KMS 加密的对象，所需成本仅为以前的一小部分。

每个请求者至少获取一次唯一存储桶级密钥，以确保在 AWS KMS CloudTrail 事件中捕获请求者对密钥的访问权限。当调用方使用不同的角色或账户，或使用具有不同范围限定策略的相同角色时，Amazon S3 会将其视为不同的请求者。AWS KMS 节省的请求反映了请求者的数量、请求模式和所请求对象的相对年限。例如，减少请求者数量，在有限的时间窗口内请求多个对象，并使用相同的存储桶级密钥进行加密，可以节省更多费用。

**注意**  
利用 S3 存储桶密钥，可通过使用桶级密钥减少向 AWS KMS 发出的面向 `Encrypt`、`GenerateDataKey` 和 `Decrypt` 操作的请求数，从而节省 AWS KMS 请求成本。根据设计，利用此存储桶级密钥的后续请求不会产生 AWS KMS API 请求或根据 AWS KMS 密钥策略验证访问权限。

配置 S3 存储桶密钥时，存储桶中已存在的对象不使用 S3 存储桶密钥。要为现有对象配置 S3 存储桶密钥，可以使用 `CopyObject` 操作。有关更多信息，请参阅 [在对象级别配置 S3 存储桶密钥](configuring-bucket-key-object.md)。

Amazon S3 将仅为由同一 AWS KMS key 加密的对象共享 S3 存储桶密钥。S3 存储桶密钥与 AWS KMS 创建的 KMS 密钥、[导入的密钥材料](https://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html)以及[由自定义密钥存储库支持的密钥材料](https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)兼容。

![图中显示了 AWS KMS 生成的存储桶密钥，该密钥为存储桶中的对象创建数据密钥。](http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/images/S3-Bucket-Keys.png)


## 配置 S3 存储桶密钥
<a name="configure-bucket-key"></a>

您可以通过 Amazon S3 控制台、AWS SDK、AWS CLI 或 REST API 将存储桶配置为使用 S3 存储桶密钥对新对象进行 SSE-KMS 加密。在您的存储桶上启用 S3 存储桶密钥后，使用其他指定 SSE-KMS 密钥上传的对象将使用其自己的 S3 存储桶密钥。无论您的 S3 存储桶密钥设置如何，您都可以在请求中包含带 `true` 或 `false` 值的 `x-amz-server-side-encryption-bucket-key-enabled` 标头，以覆盖存储桶设置。

在将存储桶配置为使用 S3 存储桶密钥之前，请查看 [启用 S3 存储桶密钥之前需要注意的更改](#bucket-key-changes)。

### 使用 Amazon S3 控制台配置 S3 存储桶密钥
<a name="configure-bucket-key-console"></a>

创建新存储桶时，您可以将存储桶配置为使用 S3 存储桶密钥对新对象进行 SSE-KMS 加密。您还可以通过更新存储桶属性，从而将现有存储桶配置为使用 S3 存储桶密钥对新对象进行 SSE-KMS 加密。 

有关更多信息，请参阅 [将存储桶配置为将 S3 存储桶密钥与 SSE-KMS 结合使用于新对象](configuring-bucket-key.md)。

### REST API、AWS CLI 和 AWS SDK 支持 S3 存储桶密钥
<a name="configure-bucket-key-programmatic"></a>

您可以使用 REST API、AWS CLI 或 AWS SDK 将存储桶配置为使用 S3 存储桶密钥对新对象进行 SSE-KMS 加密。您还可以在对象级别启用 S3 存储桶密钥。

有关更多信息，请参阅下列内容： 
+ [在对象级别配置 S3 存储桶密钥](configuring-bucket-key-object.md)
+ [将存储桶配置为将 S3 存储桶密钥与 SSE-KMS 结合使用于新对象](configuring-bucket-key.md)

以下 API 操作对于 SSE-KMS 支持 S3 存储桶密钥：
+ [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html)
  + `ServerSideEncryptionRule` 接受用于启用和禁用 S3 存储桶密钥的 `BucketKeyEnabled` 参数。
+ [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html)
  + `ServerSideEncryptionRule` 返回 的设置。`BucketKeyEnabled`
+ [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)、[CopyObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)、[CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) 和 [POST 对象](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
  + `x-amz-server-side-encryption-bucket-key-enabled` 请求标头在对象级别启用或禁用 S3 存储桶密钥。
+ [HeadObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html)、[GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)、[UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html)、[UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) 和 [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
  + `x-amz-server-side-encryption-bucket-key-enabled` 响应标头指示是否为对象启用或禁用了 S3 存储桶密钥。

### 使用 CloudFormation
<a name="configure-bucket-key-cfn"></a>

在 CloudFormation 中，`AWS::S3::Bucket` 资源包括名为 `BucketKeyEnabled` 的加密属性，您可以使用该属性来启用或禁用 S3 存储桶密钥。

有关更多信息，请参阅 [使用 CloudFormation](configuring-bucket-key.md#enable-bucket-key-cloudformation)。

## 启用 S3 存储桶密钥之前需要注意的更改
<a name="bucket-key-changes"></a>

在启用 S3 存储桶密钥之前，请注意以下相关更改：

### IAM 或 AWS KMS 密钥策略
<a name="bucket-key-policies"></a>

如果您现有的 AWS Identity and Access Management（IAM）策略或 AWS KMS 密钥策略使用您的对象 Amazon 资源名称（ARN）作为加密上下文来优化或限制对 KMS 密钥的访问，则这些策略将不使用 S3 存储桶密钥。S3 存储桶密钥使用存储桶 ARN 作为加密上下文。在启用 S3 存储桶密钥之前，请更新 IAM 策略或 AWS KMS 密钥策略，以将存储桶 ARN 用作加密上下文。

有关加密上下文和 S3 存储桶密钥的更多信息，请参阅[加密上下文](UsingKMSEncryption.md#encryption-context)。

### AWS KMS 的 CloudTrail 事件
<a name="bucket-key-cloudtrail"></a>

启用 S3 存储桶密钥后，AWS KMS CloudTrail 事件会记录存储桶 ARN 而不是对象 ARN。此外，您在日志中看到的 SSE-KMS 对象的 KMS CloudTrail 事件较少。因为 Amazon S3 中的密钥材料是有时间限制的，所以对 AWS KMS 的请求减少。

## 将 S3 存储桶密钥与复制功能结合使用
<a name="bucket-key-replication"></a>

您可以将 S3 存储桶密钥与同区域复制（SRR）和跨区域复制（CRR）结合使用。

当 Amazon S3 复制加密对象时，它通常会在目标存储桶中保留副本对象的加密设置。但是，如果源对象未加密且目标存储桶使用默认加密或 S3 存储桶密钥，则 Amazon S3 会使用目标存储桶的配置加密对象。

以下示例说明了 S3 存储桶密钥如何与复制结合使用。有关更多信息，请参阅 [复制加密对象（SSE-S3、SSE-KMS、DSSE-KMS、SSE-C）](replication-config-for-kms-objects.md)。 

**Example 示例 1 – 源对象使用 S3 存储桶密钥；目标存储桶使用默认加密**  
如果源对象使用 S3 存储桶密钥，但目标存储桶将默认加密与 SSE-KMS 结合使用，则副本对象将在目标存储桶中维护其 S3 存储桶密钥加密设置。目标存储桶仍将默认加密与 SSE-KMS 结合使用。  


**Example 示例 2 – 源对象未加密；目标存储桶将 S3 存储桶密钥与 SSE-KMS 结合使用**  
如果源对象未加密，而目标存储桶将 S3 存储桶密钥与 SSE-KMS 结合使用，则将通过在目标存储桶中将 S3 存储桶密钥与 SSE-KMS 结合使用来加密复制的对象。这将导致源对象的 `ETag` 与副本对象的 `ETag` 不同。您必须更新使用 `ETag` 的应用程序以应对这种差异。

## 使用 S3 存储桶密钥
<a name="using-bucket-key"></a>

有关启用和使用 S3 存储桶密钥的更多信息，请参阅以下各部分：
+ [将存储桶配置为将 S3 存储桶密钥与 SSE-KMS 结合使用于新对象](configuring-bucket-key.md)
+ [在对象级别配置 S3 存储桶密钥](configuring-bucket-key-object.md)
+ [查看 S3 存储桶密钥的设置](viewing-bucket-key-settings.md)