

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

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

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

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

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

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

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

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

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

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

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


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

您可以通过 Amazon S3 控制台、Amazon SDK、Amazon 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、Amazon CLI 和 Amazon SDK 支持 S3 存储桶密钥
<a name="configure-bucket-key-programmatic"></a>

您可以使用 REST API、Amazon CLI 或 Amazon 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.amazonaws.cn/AmazonS3/latest/API/API_PutBucketEncryption.html)
  + `ServerSideEncryptionRule` 接受用于启用和禁用 S3 存储桶密钥的 `BucketKeyEnabled` 参数。
+ [GetBucketEncryption](https://docs.amazonaws.cn/AmazonS3/latest/API/API_GetBucketEncryption.html)
  + `ServerSideEncryptionRule` 返回 的设置。`BucketKeyEnabled`
+ [PutObject](https://docs.amazonaws.cn/AmazonS3/latest/API/API_PutObject.html)、[CopyObject](https://docs.amazonaws.cn/AmazonS3/latest/API/API_CopyObject.html)、[CreateMultipartUpload](https://docs.amazonaws.cn/AmazonS3/latest/API/API_CreateMultipartUpload.html) 和 [POST 对象](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTObjectPOST.html)
  + `x-amz-server-side-encryption-bucket-key-enabled` 请求标头在对象级别启用或禁用 S3 存储桶密钥。
+ [HeadObject](https://docs.amazonaws.cn/AmazonS3/latest/API/API_HeadObject.html)、[GetObject](https://docs.amazonaws.cn/AmazonS3/latest/API/API_GetObject.html)、[UploadPartCopy](https://docs.amazonaws.cn/AmazonS3/latest/API/API_UploadPartCopy.html)、[UploadPart](https://docs.amazonaws.cn/AmazonS3/latest/API/API_UploadPart.html) 和 [CompleteMultipartUpload](https://docs.amazonaws.cn/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
  + `x-amz-server-side-encryption-bucket-key-enabled` 响应标头指示是否为对象启用或禁用了 S3 存储桶密钥。

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

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

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

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

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

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

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

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

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

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