

# 使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）
<a name="UsingKMSEncryption"></a>

**重要**  
Amazon S3 现在将具有 Amazon S3 托管密钥的服务器端加密（SSE-S3）作为 Amazon S3 中每个存储桶的基本加密级别。从 2023 年 1 月 5 日起，上传到 Amazon S3 的所有新对象都将自动加密，不会产生额外费用，也不会影响性能。S3 存储桶默认加密配置和上传的新对象的自动加密状态可在 CloudTrail 日志、S3 清单、S3 Storage Lens 存储统计管理工具和 Amazon S3 控制台中查看，并可用作 AWS CLI 和 AWS SDK 中的附加 Amazon S3 API 响应标头。有关更多信息，请参阅[默认加密常见问题解答](https://docs.aws.amazon.com/AmazonS3/latest/userguide/default-encryption-faq.html)。

服务器端加密是指由接收数据的应用程序或服务在目标位置对数据进行加密。

Amazon S3 对于上传的新对象自动启用具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）。

除非您另行指定，否则默认情况下存储桶使用 SSE-S3 来加密对象。但是，您可以选择将存储桶配置为改为使用具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS）。有关更多信息，请参阅 [使用 AWS KMS (SSE-KMS) 指定服务器端加密](specifying-kms-encryption.md)。

AWS KMS 是一项服务，可将安全、高度可用的硬件和软件结合起来，以提供可扩展到云的密钥管理系统。Amazon S3 使用具有 AWS KMS 的服务器端加密（SSE-KMS）来加密您的 S3 对象数据。此外，当为对象请求 SSE-KMS 时，S3 校验和（作为对象元数据的一部分）将以加密形式存储。有关校验和的更多信息，请参阅[在 Amazon S3 中检查对象完整性](checking-object-integrity.md)。

如果使用 KMS 密钥，则可以使用 AWS KMS，通过 [AWS 管理控制台](https://console.aws.amazon.com/kms)或 [AWS KMS API](https://docs.aws.amazon.com/kms/latest/APIReference/) 来执行以下操作：
+ 集中创建、查看、编辑、监控、启用或禁用、轮换以及安排删除 KMS 密钥。
+ 定义控制如何使用和谁可以使用 KMS 密钥的策略。
+ 审计 KMS 密钥的使用情况，以确保正确使用。[AWS KMS API](https://docs.aws.amazon.com/kms/latest/APIReference/) 支持审计，但 [AWS KMS 控制台](https://console.aws.amazon.com/kms)不支持此功能。



AWS KMS 中的安全控制可帮助您满足与加密相关的合规性要求。您可以利用这些 KMS 密钥来保护在 Amazon S3 存储桶中的数据。将 SSE-KMS 加密用于 S3 存储桶时，AWS KMS keys 必须位于该存储桶所在的同一区域中。

使用 AWS KMS keys 密钥需要支付额外费用。有关更多信息，请参阅 *AWS Key Management Service 开发人员指南*中的 [AWS KMS key 概念](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms_keys)和 [AWS KMS 定价](https://aws.amazon.com/kms/pricing)。

有关支持 IAM 用户访问 KMS 加密的存储桶的说明，请参阅[我的 Amazon S3 存储桶默认使用自定义 AWS KMS 密钥进行加密。我如何允许用户从存储桶下载和上传到存储桶？](https://repost.aws/knowledge-center/s3-bucket-access-default-encryption)（位于 AWS re:Post 知识中心中）。

**权限**  
要成功向 Amazon S3 发出 `PutObject` 请求以使用 AWS KMS 密钥来加密对象，您需要对密钥拥有 `kms:GenerateDataKey` 权限。要下载使用 AWS KMS key加密的对象，您需要对密钥拥有 `kms:Decrypt` 权限。要[执行分段上传](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html#mpuAndPermissions)以使用 AWS KMS key来加密对象，您必须对密钥拥有 `kms:GenerateDataKey` 和 `kms:Decrypt` 权限。

**重要**  
仔细查看在您的 KMS 密钥政策中授予的权限。始终将客户自主管理型 KMS 密钥政策权限仅限制为必须访问相关 AWS KMS 密钥操作的 IAM 主体和 AWS 服务。有关更多信息，请参阅[AWS KMS 中的密钥策略](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)。

**Topics**
+ [

## AWS KMS keys
](#aws-managed-customer-managed-keys)
+ [

## Amazon S3 存储桶密钥
](#sse-kms-bucket-keys)
+ [

## 需要服务器端加密
](#require-sse-kms)
+ [

## 加密上下文
](#encryption-context)
+ [

## 发送对 AWS KMS 加密对象的请求
](#aws-signature-version-4-sse-kms)
+ [

# 使用 AWS KMS (SSE-KMS) 指定服务器端加密
](specifying-kms-encryption.md)
+ [

# 使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本
](bucket-key.md)

## AWS KMS keys
<a name="aws-managed-customer-managed-keys"></a>

当您使用具有 AWS KMS 的服务器端加密（SSE-KMS）时，您可以使用默认的 [AWS 托管式密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-managed-cmk)，也可以指定您已创建的[客户托管式密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk)。AWS KMS 支持*信封加密*。S3 将 AWS KMS 特征用于*信封加密*来进一步保护您的数据。信封加密是一种加密方法，它使用数据密钥对明文数据进行加密，然后使用 KMS 密钥对该数据密钥进行加密。有关信封加密的更多信息，请参阅 *AWS Key Management Service 开发人员指南*中的[信封加密](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#enveloping)。

如果未指定客户托管密钥，首次将使用 SSE-KMS 加密的对象添加到存储桶时，Amazon S3 会自动在 AWS 账户 中创建 AWS 托管式密钥。默认情况下，Amazon S3 将此 KMS 密钥用于 SSE-KMS。

**注意**  
通过 SSE-KMS（使用 [AWS 托管式密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-managed-cmk)）加密的对象不能跨账户共享。如果您需要跨账户共享 SSE-KMS 数据，则必须使用来自 AWS KMS 的[客户自主管理型密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk)。

如果要使用客户托管式密钥进行 SSE-KMS 加密，可以在配置 SSE-KMS 之前创建对称加密客户托管式密钥。然后，为存储桶配置 SSE-KMS 时，请指定现有的客户托管密钥。有关对称加密密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[对称加密 KMS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#symmetric-cmks)。

创建客户托管密钥可为您提供更大的灵活性和控制力。例如，您可以创建、轮换和禁用客户托管密钥。您还可以定义访问控制和审核用于保护数据的客户托管密钥。有关客户托管式密钥和 AWS 托管式密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[客户密钥和 AWS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#key-mgmt)。

**注意**  
与标准 KMS 密钥不同，当您将服务器端加密与存储在外部密钥存储中的客户托管式密钥结合使用时，您有责任确保密钥材料的可用性和耐久性。有关外部密钥存储及其如何更改责任共担模式的更多信息，请参阅《AWS Key Management Service 开发者指南》**中的[外部密钥存储](https://docs.aws.amazon.com//kms/latest/developerguide/keystore-external.html)。

### 使用 SSE-KMS 加密进行跨账户操作
<a name="sse-kms-cross-account-operations"></a>

在对跨账户操作使用加密时，请注意以下事项：
+ 如果未在请求时提供 AWS KMS key Amazon 资源名称（ARN）或别名，也未通过存储桶的默认加密配置提供它们，则使用发出上传的账户中的 AWS 托管式密钥（`aws/s3`）来进行加密，并且加密需要使用此密钥。
+ 当进行上传和访问的 AWS Identity and Access Management（IAM）主体来自同一 AWS 账户时，AWS 托管式密钥（`aws/s3`）可以用作跨账户操作的 KMS 密钥。
+ 如果您希望授予对 S3 对象的跨账户访问权限，请使用客户自主管理型密钥。您可以配置客户托管式密钥的策略，以便允许从其他账户进行访问。
+ 如果您指定客户托管式 KMS 密钥，我们建议您使用完全限定的 KMS 密钥 ARN。如果您改为使用 KMS 密钥别名，AWS KMS 将解析请求者账户中的密钥。这一行为可能导致使用属于请求者而不是存储桶拥有者的 KMS 密钥来加密数据。
+ 您必须指定您（请求者）已被授予 `Encrypt` 权限的密钥。有关更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[允许密钥用户使用 KMS 密钥进行加密操作](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-users-crypto)。

有关何时使用客户自主管理型密钥和 AWS KMS 托管密钥的更多信息，请参阅[我是应使用 AWS 托管式密钥 还是使用客户自主管理型密钥来加密 Amazon S3 中的对象？](https://aws.amazon.com/premiumsupport/knowledge-center/s3-object-encryption-keys/)

### SSE-KMS 加密工作流程
<a name="sse-kms-encryption-workflow"></a>

如果您选择使用 AWS 托管式密钥或客户托管式密钥加密数据，则 AWS KMS 和 Amazon S3 执行以下信封加密操作：

1. Amazon S3 请求明文[数据密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#data-keys)以及使用指定 KMS 密钥加密的数据密钥的副本。

1. AWS KMS 生成数据密钥，使用 KMS 密钥为其进行加密，然后将明文数据密钥和加密的数据密钥发送到 Amazon S3。

1. Amazon S3 使用数据密钥加密数据，并在使用后尽快从内存中删除该明文密钥。

1. Amazon S3 将加密的数据密钥作为元数据与加密数据一起存储。

当请求解密数据时，Amazon S3 和 AWS KMS 将执行以下操作：

1. Amazon S3 在 `Decrypt` 请求中向 AWS KMS 发送加密的数据密钥。

1. AWS KMS 使用相同的 KMS 密钥为加密的数据密钥解密，然后将明文数据密钥返回到 Amazon S3。

1. Amazon S3 使用明文数据密钥解密已加密的数据，并尽快从内存中删除该明文数据密钥。

**重要**  
在 Amazon S3 中使用 AWS KMS key 进行服务器端加密时，您必须选择对称加密 KMS 密钥。Amazon S3 仅支持对称加密 KMS 密钥。有关这些密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[对称加密 KMS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#symmetric-cmks)。

### 审计 SSE-KMS 加密
<a name="sse-kms-encryption-audit"></a>

要识别指定 SSE-KMS 的请求，您可以使用 Amazon S3 Storage Lens 存储统计管理工具指标中的 **All SSE-KMS requests**（所有 SSE-KMS 请求）和 **% all SSE-KMS requests**（所有 SSE-KMS 请求的百分比）指标。S3 Storage Lens 存储统计管理工具是一项云存储分析功能，您可以使用它在整个组织范围内了解对象存储的使用情况和活动。还可以使用启用 SSE-KMS 的存储桶计数和启用 SSE-KMS 的存储桶百分比，来了解使用 SSE-KMS 进行[默认存储桶加密](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html)的存储桶计数。有关更多信息，请参阅[使用 S3 Storage Lens 存储统计管理工具访问存储活动和使用情况](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage_lens.html?icmpid=docs_s3_user_guide_UsingKMSEncryption.html)。有关指标的完整列表，请参阅 [S3 Storage Lens 存储统计管理工具指标词汇表](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage_lens_metrics_glossary.html?icmpid=docs_s3_user_guide_UsingKMSEncryption.html)。

要审计为 SSE-KMS 加密数据使用 AWS KMS 密钥的情况，您可以使用 AWS CloudTrail 日志。您可以深入了解自己的[加密操作](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations)，例如 [https://docs.aws.amazon.com/kms/latest/developerguide/ct-generatedatakey.html](https://docs.aws.amazon.com/kms/latest/developerguide/ct-generatedatakey.html) 和 [https://docs.aws.amazon.com/kms/latest/developerguide/ct-decrypt.html](https://docs.aws.amazon.com/kms/latest/developerguide/ct-decrypt.html)。CloudTrail 支持多种[属性值](https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_LookupEvents.html)来筛选您的搜索，包括事件名称、用户名和事件源。

## Amazon S3 存储桶密钥
<a name="sse-kms-bucket-keys"></a>

当您配置使用 AWS KMS 的服务器端加密（SSE-KMS）时，您可以将存储桶配置为使用 S3 存储桶密钥实现 SSE-KMS。使用 SSE-KMS 的存储桶级别密钥可以通过减少从 Amazon S3 到 AWS KMS 的流量请求，从而使您可以将 AWS KMS 请求成本最高降低 99％。

当您将存储桶配置为使用 S3 存储桶密钥对新对象实现 SSE-KMS 时，AWS KMS 会生成存储桶级别密钥，该密钥用于为存储桶中的对象创建唯一的[数据密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys)。此 S3 存储桶密钥在 Amazon S3 内限时使用，从而进一步减少了 Amazon S3 向 AWS KMS 发出请求以完成加密操作的需求。有关使用 S3 存储桶密钥的更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

## 需要服务器端加密
<a name="require-sse-kms"></a>

如果要求对特定 Amazon S3 存储桶中的所有对象进行服务器端加密，请使用存储桶策略。例如，如果请求不包含用于请求服务器端加密（SSE-KMS）的 `x-amz-server-side-encryption-aws-kms-key-id` 标头，则下面的存储桶策略将拒绝所有人的上传对象（`s3:PutObject`）权限。

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

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Id":"PutObjectPolicy",
   "Statement":[{
         "Sid":"DenyObjectsThatAreNotSSEKMS",
         "Effect":"Deny",
         "Principal":"*",
         "Action":"s3:PutObject",
         "Resource":"arn:aws:s3:::amzn-s3-demo-bucket1/*",
         "Condition":{
            "Null":{
               "s3:x-amz-server-side-encryption-aws-kms-key-id":"true"
            }
         }
      }
   ]
}
```

------

如要求使用特定 AWS KMS key 对存储桶中的对象进行加密，可以使用 `s3:x-amz-server-side-encryption-aws-kms-key-id` 条件键。要指定 KMS 密钥，必须使用 `arn:aws:kms:region:acct-id:key/key-id` 格式的键 Amazon 资源名称（ARN）。AWS Identity and Access Management 不验证 `s3:x-amz-server-side-encryption-aws-kms-key-id` 的字符串是否存在。

**注意**  
在上传对象时，可以使用 `x-amz-server-side-encryption-aws-kms-key-id` 标头指定 KMS 密钥，也可以依赖您的[默认存储桶加密配置](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html)。如果 PutObject 请求在 `x-amz-server-side-encryption` 标头中指定 `aws:kms`，但未指定 `x-amz-server-side-encryption-aws-kms-key-id` 标头，则 Amazon S3 会假定您要使用 AWS 托管式密钥。无论如何，Amazon S3 用于对象加密的 AWS KMS 密钥 ID 必须与策略中的 AWS KMS 密钥 ID 匹配，否则 Amazon S3 会拒绝请求。

要查看 Amazon S3 特定条件键的列表，请参阅《Service Authorization Reference》**中的 [Condition keys for Amazon S3](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazons3.html#amazons3-policy-keys)。

## 加密上下文
<a name="encryption-context"></a>

*加密上下文*是一组键值对，其中包含有关数据的其他上下文信息。加密上下文没有加密。在为加密操作指定加密上下文时，Amazon S3 必须指定与解密操作相同的加密上下文。否则，解密将失败。AWS KMS 会将加密上下文用作[其他已经过验证的数据](https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/concepts.html#digital-sigs) (AAD) 以支持[经过身份验证的加密](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations#digital-sigs)。有关加密上下文的更多信息，请参阅 *AWS Key Management Service 开发人员指南*中的[加密上下文](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)。

默认情况下，Amazon S3 使用对象或存储桶 Amazon 资源名称（ARN）作为加密上下文对：
+ **如果您在不启用 S3 存储桶密钥的情况下使用 SSE-KMS**，则将对象 ARN 用作加密上下文。

  ```
  arn:aws:s3:::object_ARN
  ```
+ **如果您使用 SSE-KMS 并启用 S3 存储桶密钥**，则将存储桶 ARN 用作加密上下文。有关 S3 存储桶的更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

  ```
  arn:aws:s3:::bucket_ARN
  ```

您可以选择使用 [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#API_PutObject_RequestSyntax) 请求中的 `x-amz-server-side-encryption-context` 标头提供其他的加密上下文对。但是，由于加密上下文未加密，请确保它不包含敏感信息。Amazon S3 将此额外的密钥对与默认加密上下文一起存储。当处理 `PUT` 请求时，Amazon S3 会将 `aws:s3:arn` 的默认加密上下文附加到您提供的上下文中。

您可以使用加密上下文来标识和分类加密操作。您还可以使用默认的加密上下文 ARN 值来跟踪 AWS CloudTrail 中的相关请求，方法是通过查看哪个 Amazon S3 ARN 与哪个加密密钥一起使用。

在 CloudTrail 日志文件的 `requestParameters` 字段中，加密上下文与以下内容类似。

```
"encryptionContext": {
    "aws:s3:arn": "arn:aws:s3:::amzn-s3-demo-bucket1/file_name"
}
```

在将 SSE-KMS 与可选的 S3 存储桶密钥特征一起使用时，加密上下文值是存储桶的 ARN。

```
"encryptionContext": {
    "aws:s3:arn": "arn:aws:s3:::amzn-s3-demo-bucket1"
}
```

## 发送对 AWS KMS 加密对象的请求
<a name="aws-signature-version-4-sse-kms"></a>

**重要**  
对 AWS KMS 加密对象的所有 `GET` 和 `PUT` 请求必须使用安全套接字层协议（SSL）和传输层安全性协议（TLS）发出。还必须使用有效的凭证对请求进行签名，例如 AWS 签名版本 4（或 AWS 签名版本 2）。

AWS 签名版本 4 是将身份验证信息添加到通过 HTTP 发送的 AWS 请求的过程。出于安全考虑，大多数 AWS 请求都必须使用访问密钥（包括访问密钥 ID 和秘密访问密钥）进行签名。这两个密钥通常称为您的安全凭证。有关更多信息，请参阅[对请求进行身份验证（AWS Signature Version 4）](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)和 [Signature Version 4 签名过程](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)。

**重要**  
如果对象使用 SSE-KMS，则不应对 `GET` 请求和 `HEAD` 请求发送加密请求标头。否则，您会收到 HTTP 400 错误请求错误。

**Topics**
+ [

## AWS KMS keys
](#aws-managed-customer-managed-keys)
+ [

## Amazon S3 存储桶密钥
](#sse-kms-bucket-keys)
+ [

## 需要服务器端加密
](#require-sse-kms)
+ [

## 加密上下文
](#encryption-context)
+ [

## 发送对 AWS KMS 加密对象的请求
](#aws-signature-version-4-sse-kms)
+ [

# 使用 AWS KMS (SSE-KMS) 指定服务器端加密
](specifying-kms-encryption.md)
+ [

# 使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本
](bucket-key.md)

# 使用 AWS KMS (SSE-KMS) 指定服务器端加密
<a name="specifying-kms-encryption"></a>

默认情况下，所有 Amazon S3 存储桶都配置了加密，所有上传到 S3 存储桶的新对象都会自动静态加密。具有 Amazon S3 托管密钥的服务器端加密（SSE-S3）是 Amazon S3 中每个存储桶的默认加密配置。要使用其它类型的加密，您可以指定要在 S3 `PUT` 请求中使用的服务器端加密类型，也可以在目标存储桶中更新默认加密配置。

如果您想在 `PUT` 请求中指定不同的加密类型，则可以使用具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS）、具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）或具有客户提供的密钥的服务器端加密（SSE-C）。如果您想在目标存储桶中设置不同的默认加密配置，则可以使用 SSE-KMS 或 DSSE-KMS。

有关更改通用存储桶的默认加密配置的更多信息，请参阅[配置默认加密](default-bucket-encryption.md)。

在将存储桶的默认加密配置更改为 SSE-KMS 时，不会更改存储桶中现有 Amazon S3 对象的加密类型。要在将默认加密配置更新为 SSE-KMS 后更改先前存在对象的加密类型，可以使用 Amazon S3 批量操作。您为 S3 批量操作提供对象列表，而批量操作调用相应的 API 操作。可以使用 [复制对象](batch-ops-copy-object.md) 操作来复制现有对象，这会将这些对象写回到与 SSE-KMS 加密对象相同的存储桶中。单个批量操作作业可对数十亿个对象执行指定操作。有关更多信息，请参阅[使用批量操作批量执行对象操作](batch-ops.md)和 *AWS Storage Blog* 博客文章 [How to retroactively encrypt existing objects in Amazon S3 using S3 Inventory, Amazon Athena, and S3 Batch Operations](https://aws.amazon.com/blogs/security/how-to-retroactively-encrypt-existing-objects-in-amazon-s3-using-s3-inventory-amazon-athena-and-s3-batch-operations/)。

您可以使用 Amazon S3 控制台、REST API 操作、AWS SDK 和 AWS Command Line Interface（AWS CLI）指定 SSE-KMS。有关更多信息，请参阅以下主题。

**注意**  
您可以在 Amazon S3 中使用多区域 AWS KMS keys。但是，Amazon S3 目前将多区域密钥视为单区域密钥，且不使用密钥的多区域特征。有关更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的 [Using multi-Region keys](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)。

**注意**  
如果您希望使用其它账户拥有的 KMS 密钥，您必须有权使用该密钥。有关 KMS 密钥的跨账户权限的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[创建其他账户可以使用的 KMS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/key-policy-modifying-external-accounts.html#cross-account-console)。

## 使用 S3 控制台
<a name="add-object-encryption-kms"></a>

本主题描述如何使用 Amazon S3 控制台，将对象的加密类型设置或更改为使用具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS）。

**注意**  
如果对象小于 5 GB，则可以更改对象的加密。如果对象大于 5GB，必须使用 [AWS CLI](mpu-upload-object.md#UsingCLImpUpload) 或 [AWS SDK](CopyingObjectsMPUapi.md) 来更改对象的加密。
有关更改对象的加密所需的其它权限的列表，请参阅 [Amazon S3 API 操作所需的权限](using-with-s3-policy-actions.md)。有关授予此权限的示例策略，请参阅[Amazon S3 基于身份的策略示例](example-policies-s3.md)。
如果更改对象的加密，则会创建一个新对象来替换旧对象。如果启用 S3 版本控制，则会创建对象的新版本，而现有对象将变为旧版本。更改属性的角色也会成为新对象（或对象版本）的拥有者。

**添加或更改对象的加密**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在导航窗格中，选择**存储桶**，然后选择**通用存储桶**选项卡。导航到包含要更改的对象的 Amazon S3 存储桶或文件夹。

1. 选中要更改的对象所对应的复选框。

1. 在**操作**菜单上，从显示的选项列表中选择**编辑服务器端加密**。

1. 滚动到**服务器端加密**部分。

1. 在**加密设置**下，选择**使用默认加密的存储桶设置**或**覆盖默认加密的存储桶设置**。
**重要**  
如果您将 SSE-KMS 选项用于默认加密配置，则您将受到 AWS KMS 的每秒请求数（RPS）限额限制。有关 AWS KMS 限额以及如何请求增加限额的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[限额](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html)。

1. 如果您选择**覆盖默认加密的存储桶设置**，请配置以下加密设置。

   1. 在**加密类型**下，选择**具有 AWS Key Management Service 密钥的服务器端加密（SSE-KMS）**。

   1. 在 **AWS KMS 密钥**下，执行以下操作以选择您的 KMS 密钥：
      + 要从可用的 KMS 密钥列表中进行选择，请选择**从您的 AWS KMS keys 中进行选择**，然后从可用密钥的列表中选择您的 **KMS 密钥**。

        AWS 托管式密钥（`aws/s3`）和您的客户自主管理型密钥都显示在此列表中。有关客户自主管理型密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[客户密钥和 AWS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#key-mgmt)。
      + 要输入 KMS 密钥 ARN，请选择**输入 AWS KMS key ARN**，然后在显示的字段中输入您的 KMS 密钥 ARN。
      + 要在 AWS KMS 控制台中创建新的客户自主管理型密钥，请选择**创建 KMS 密钥**。

        有关创建 AWS KMS key 的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[创建密钥](https://docs.aws.amazon.com//kms/latest/developerguide/create-keys.html)。
**重要**  
您只能使用与存储桶所在相同的 AWS 区域中可用的 KMS 密钥。Amazon S3 控制台仅列出与存储桶位于同一区域中的前 100 个 KMS 密钥。要使用未列出的 KMS 密钥，您必须输入 KMS 密钥 ARN。如果您希望使用其他账户拥有的 KMS 密钥，则必须首先有权使用该密钥，然后必须输入相应的 KMS 密钥 ARN。  
Amazon S3 仅支持对称加密 KMS 密钥，不支持非对称 KMS 密钥。有关更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[确定对称和非对称 KMS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/find-symm-asymm.html)。

1. 在**其它复制设置**下，选择是要**复制源设置**、**请勿指定设置**还是**指定设置**。**复制源设置**是默认选项。如果您只想复制不带源设置属性的对象，请选择**请勿指定设置**。选择**指定设置**，来指定存储类、ACL、对象标签、元数据、服务器端加密和其它校验和的设置。

1. 选择**保存更改**。

**注意**  
此操作将加密应用于所有指定的对象。加密文件夹时，请等待保存操作完成，然后再将新对象添加到文件夹。

## 使用 REST API
<a name="KMSUsingRESTAPI"></a>

创建对象时（即上传新对象或复制现有对象时），您可以指定使用具有 AWS KMS keys 的服务器端加密（SSE-KMS）来加密数据。为此，请将 `x-amz-server-side-encryption` 标头添加到请求。将标头的值设置为加密算法 `aws:kms`。Amazon S3 通过返回响应标头 `x-amz-server-side-encryption` 来确认已使用 SSE-KMS 存储您的对象。

如果您指定值为 `x-amz-server-side-encryption` 的 `aws:kms` 标头，则还可以使用以下请求标头：
+ `x-amz-server-side-encryption-aws-kms-key-id`
+ `x-amz-server-side-encryption-context`
+ `x-amz-server-side-encryption-bucket-key-enabled`

**Topics**
+ [

### 支持 SSE-KMS 的 Amazon S3 REST API 操作
](#sse-request-headers-kms)
+ [

### 加密上下文（`x-amz-server-side-encryption-context`）
](#s3-kms-encryption-context)
+ [

### AWS KMS 密钥 ID（`x-amz-server-side-encryption-aws-kms-key-id`）
](#s3-kms-key-id-api)
+ [

### S3 桶密钥（`x-amz-server-side-encryption-aws-bucket-key-enabled`）
](#bucket-key-api)

### 支持 SSE-KMS 的 Amazon S3 REST API 操作
<a name="sse-request-headers-kms"></a>

以下 REST API 操作接受 `x-amz-server-side-encryption`、`x-amz-server-side-encryption-aws-kms-key-id` 和 `x-amz-server-side-encryption-context` 请求标头。
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) – 使用 `PUT` API 操作上传数据时，您可以指定这些请求标头。
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) – 复制对象时，您同时具有源对象和目标对象。如果使用 `CopyObject` 操作传递 SSE-KMS 标头，这些标头仅应用于目标对象。复制现有对象时，不论源对象是否已加密，都不会对目标对象加密，除非您显式请求服务器端加密。
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) – 使用 `POST` 操作上传对象时，可在表单字段（而不是在请求标头）中提供相同的信息。
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) – 使用分段上传 API 操作上传大型对象时，可以指定这些标头。您可以在 `CreateMultipartUpload` 请求中指定这些标头。

使用服务器端加密存储对象时，以下 REST API 操作的响应标头将返回 `x-amz-server-side-encryption` 标头。
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html)

**重要**  
如果您不让使用安全套接字协议（SSL）、传输层安全性协议（TLS）或签名版本 4 针对受 AWS KMS 保护的对象发出所有 `GET` 和 `PUT` 请求，则这些请求都将失败。
如果对象使用 SSE-KMS，则不应对 `GET` 请求和 `HEAD` 请求发送加密请求标头，否则将显示 HTTP 400 BadRequest 错误。

### 加密上下文（`x-amz-server-side-encryption-context`）
<a name="s3-kms-encryption-context"></a>

如果您指定 `x-amz-server-side-encryption:aws:kms`，Amazon S3 API 将支持带有 `x-amz-server-side-encryption-context` 标头的加密上下文。加密上下文是一组键值对，其中包含有关数据的其他上下文信息。

Amazon S3 会自动使用对象或存储桶 Amazon Resource Name（ARN）作为加密上下文对。如果您在不启用 S3 存储桶密钥的情况下使用 SSE-KMS，则将对象 ARN 用作加密上下文；例如 `arn:aws:s3:::object_ARN`。但是，如果您使用 SSE-KMS 并启用 S3 存储桶密钥，则将存储桶 ARN 用于加密上下文；例如 `arn:aws:s3:::bucket_ARN`。

您可以选择使用 `x-amz-server-side-encryption-context` 标头提供其他的加密上下文对。但是，由于加密上下文未加密，请确保其中不包含敏感信息。Amazon S3 将此额外的密钥对与默认加密上下文一起存储。

有关 Amazon S3 中加密上下文的信息，请参阅 [加密上下文](UsingKMSEncryption.md#encryption-context)。有关加密上下文的一般信息，请参阅 *AWS Key Management Service 开发人员指南*中的 [AWS Key Management Service 概念 - 加密上下文](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)。

### AWS KMS 密钥 ID（`x-amz-server-side-encryption-aws-kms-key-id`）
<a name="s3-kms-key-id-api"></a>

您可以使用 `x-amz-server-side-encryption-aws-kms-key-id` 标头指定用于保护数据的客户自主管理型密钥的 ID。如果您指定 `x-amz-server-side-encryption:aws:kms` 标头但未提供 `x-amz-server-side-encryption-aws-kms-key-id` 标头，Amazon S3 将使用 AWS 托管式密钥（`aws/s3`）来保护数据。如果要使用客户托管密钥，则必须提供客户托管密钥的 `x-amz-server-side-encryption-aws-kms-key-id` 标头。

**重要**  
在 Amazon S3 中使用 AWS KMS key 进行服务器端加密时，您必须选择对称加密 KMS 密钥。Amazon S3 仅支持对称加密 KMS 密钥。有关这些密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[对称加密 KMS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#symmetric-cmks)。

### S3 桶密钥（`x-amz-server-side-encryption-aws-bucket-key-enabled`）
<a name="bucket-key-api"></a>

您可以使用 `x-amz-server-side-encryption-aws-bucket-key-enabled` 请求标头在对象级别启用或禁用 S3 存储桶密钥。S3 存储桶密钥通过减少从 Amazon S3 到 AWS KMS 的请求流量来降低您的 AWS KMS 请求成本。有关更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

如果您指定 `x-amz-server-side-encryption:aws:kms` 标头但未提供 `x-amz-server-side-encryption-aws-bucket-key-enabled` 标头，则您的对象将使用目标存储桶的 S3 存储桶密钥设置来加密对象。有关更多信息，请参阅 [在对象级别配置 S3 存储桶密钥](configuring-bucket-key-object.md)。

## 使用 AWS CLI
<a name="KMSUsingCLI"></a>

要使用以下示例 AWS CLI 命令，请将 `user input placeholders` 替换为您自己的信息。

当您上传新对象或复制现有对象时，可以指定使用具有 AWS KMS 密钥的服务器端加密来加密数据。为此，请将 `--server-side-encryption aws:kms` 标头添加到请求。使用 `--ssekms-key-id example-key-id` 添加您创建的[客户托管式 AWS KMS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#customer-cmk)。如果您指定 `--server-side-encryption aws:kms`，但未提供 AWS KMS 密钥 ID，Amazon S3 将使用 AWS 托管式密钥。

```
aws s3api put-object --bucket amzn-s3-demo-bucket --key example-object-key --server-side-encryption aws:kms --ssekms-key-id example-key-id --body filepath
```

此外，您还可以通过添加 `--bucket-key-enabled` 或 `--no-bucket-key-enabled` 在 PUT 或 COPY 操作中启用或禁用 Amazon S3 存储桶密钥。Amazon S3 存储桶密钥可以通过减少从 Amazon S3 到 AWS KMS 的请求流量来降低您的 AWS KMS 请求成本。有关更多信息，请参阅[使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](https://docs.aws.amazon.com//AmazonS3/latest/userguide/bucket-key.html)。

```
aws s3api put-object --bucket amzn-s3-demo-bucket --key example-object-key --server-side-encryption aws:kms --bucket-key-enabled --body filepath
```

您可以通过将未加密的对象复制回原位来加密该对象以使用 SSE-KMS。

```
aws s3api copy-object --bucket amzn-s3-demo-bucket --key example-object-key --body filepath --bucket amzn-s3-demo-bucket --key example-object-key --sse aws:kms --sse-kms-key-id example-key-id --body filepath
```

## 使用 AWS SDK
<a name="kms-using-sdks"></a>

使用 AWS SDK 时，您可以请求 Amazon S3 使用 AWS KMS keys 进行服务器端加密。以下示例展示了如何将 SSE-KMS 与适用于 Java 和 .NET 的 AWS SDK 结合使用。有关其它 SDK 的信息，请参阅 AWS 开发人员中心上的[示例代码和库](https://aws.amazon.com/code)。

**重要**  
在 Amazon S3 中使用 AWS KMS key 进行服务器端加密时，您必须选择对称加密 KMS 密钥。Amazon S3 仅支持对称加密 KMS 密钥。有关这些密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[对称加密 KMS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#symmetric-cmks)。

### `CopyObject` 操作
<a name="kms-copy-operation"></a>

在复制对象时，您添加相同的请求属性（`ServerSideEncryptionMethod` 和 `ServerSideEncryptionKeyManagementServiceKeyId`）来请求 Amazon S3 使用 AWS KMS key。有关复制对象的更多信息，请参阅 [复制、移动和重命名对象](copy-object.md)。

### `PUT` 操作
<a name="kms-put-operation"></a>

------
#### [ Java ]

当使用适用于 Java 的 AWS SDK 上传对象时，您可以通过添加 `SSEAwsKeyManagementParams` 属性来请求 Amazon S3 使用 AWS KMS key，如以下请求所示：

```
PutObjectRequest putRequest = new PutObjectRequest(bucketName,
   keyName, file).withSSEAwsKeyManagementParams(new SSEAwsKeyManagementParams());
```

在这种情况下，Amazon S3 使用 AWS 托管式密钥（`aws/s3`）。有关更多信息，请参阅 [使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）](UsingKMSEncryption.md)。您可以选择创建对称加密 KMS 密钥，并在请求中指定该密钥，如以下示例所示：

```
PutObjectRequest putRequest = new PutObjectRequest(bucketName,
   keyName, file).withSSEAwsKeyManagementParams(new SSEAwsKeyManagementParams(keyID));
```

有关创建客户托管密钥的更多信息，请参阅 *AWS Key Management Service 开发人员指南*中的[对 AWS KMS API 进行编程](https://docs.aws.amazon.com/kms/latest/developerguide/programming-top.html)。

有关上传对象的工作代码示例，请参阅以下主题。要使用这些示例，您必须更新这些代码示例并提供加密信息，如上述代码片段所示。
+ 有关在单个操作中上传对象，请参阅 [上传对象](upload-objects.md)。
+ 有关使用高级或低级分段上传 API 操作的分段上传，请参阅[使用分段上传操作上传对象](mpu-upload-object.md)。

------
#### [ .NET ]

当使用适用于 .NET 的 AWS SDK 上传对象时，您可以通过添加 `ServerSideEncryptionMethod` 属性来请求 Amazon S3 使用 AWS KMS key，如以下请求所示：

```
PutObjectRequest putRequest = new PutObjectRequest
 {
     BucketName = amzn-s3-demo-bucket,
     Key = keyName,
     // other properties
     ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS
 };
```

在这种情况下，Amazon S3 使用 AWS 托管式密钥。有关更多信息，请参阅 [使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）](UsingKMSEncryption.md)。您可以选择创建自己的对称加密客户自主管理型密钥，并在请求中指定该密钥，如以下示例所示：

```
PutObjectRequest putRequest1 = new PutObjectRequest
{
  BucketName = amzn-s3-demo-bucket,
  Key = keyName,
  // other properties
  ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS,
  ServerSideEncryptionKeyManagementServiceKeyId = keyId
};
```

有关创建客户托管密钥的更多信息，请参阅 *AWS Key Management Service 开发人员指南*中的[对 AWS KMS API 进行编程](https://docs.aws.amazon.com/kms/latest/developerguide/programming-top.html)。

有关上传对象的工作代码示例，请参阅以下主题。要使用这些示例，您必须更新这些代码示例并提供加密信息，如上述代码片段所示。
+ 有关在单个操作中上传对象，请参阅 [上传对象](upload-objects.md)。
+ 有关使用高级或低级分段上传 API 操作的分段上传，请参阅[使用分段上传操作上传对象](mpu-upload-object.md)。

------

### 预签名 URL
<a name="kms-presigned-urls"></a>

------
#### [ Java ]

在为使用 AWS KMS key加密的对象创建预签名 URL 时，您必须显式指定签名版本 4，如以下示例所示：

```
ClientConfiguration clientConfiguration = new ClientConfiguration();
clientConfiguration.setSignerOverride("AWSS3V4SignerType");
AmazonS3Client s3client = new AmazonS3Client(
        new ProfileCredentialsProvider(), clientConfiguration);
...
```

有关代码示例，请参阅 [使用预签名 URL 共享对象](ShareObjectPreSignedURL.md)。

------
#### [ .NET ]

在为使用 AWS KMS key加密的对象创建预签名 URL 时，您必须显式指定签名版本 4，如以下示例所示：

```
AWSConfigs.S3Config.UseSignatureVersion4 = true;
```

有关代码示例，请参阅 [使用预签名 URL 共享对象](ShareObjectPreSignedURL.md)。

------

# 使用 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)

# 将存储桶配置为将 S3 存储桶密钥与 SSE-KMS 结合使用于新对象
<a name="configuring-bucket-key"></a>

当您配置具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS）时，您可以将存储桶配置为使用 S3 存储桶密钥对新对象进行 SSE-KMS 加密。S3 存储桶密钥可减少从 Amazon S3 到 AWS KMS 的请求流量，从而降低 SSE-KMS 的成本。有关更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

您可以使用 Amazon S3 控制台、REST API、AWS SDK、AWS Command Line Interface（AWS CLI）或 CloudFormation 将存储桶配置为使用 S3 存储桶密钥对新对象进行 SSE-KMS 加密。如果要为现有对象启用或禁用 S3 存储桶密钥，则可以使用 `CopyObject` 操作。有关更多信息，请参阅[在对象级别配置 S3 存储桶密钥](configuring-bucket-key-object.md)和[使用批量操作为 SSE-KMS 启用 S3 存储桶密钥](batch-ops-copy-example-bucket-key.md)。

当为源存储桶或目标存储桶启用 S3 存储桶密钥时，加密上下文将是存储桶 Amazon Resource Name（ARN），而不是对象 ARN，例如 `arn:aws:s3:::bucket_ARN`。您需要更新 IAM 策略才能将存储桶 ARN 用于加密上下文。有关更多信息，请参阅 [S3 存储桶密钥和复制](replication-config-for-kms-objects.md#bk-replication)。

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

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

**Topics**

## 使用 S3 控制台
<a name="enable-bucket-key"></a>

在 S3 控制台中，您可以为新存储桶或现有存储桶启用或禁用 S3 存储桶密钥。S3 控制台中的对象从存储桶配置中继承其 S3 存储桶密钥设置。当您为存储桶启用 S3 存储桶密钥时，您上传到存储桶的新对象将利用 S3 存储桶密钥进行 SSE-KMS 加密。

**在启用了 S3 存储桶密钥的存储桶中上传，复制或修改对象**  
如果您在启用了 S3 存储桶密钥的存储桶中上传、修改或复制对象，则该对象的 S3 存储桶密钥设置可能会更新以与存储桶配置保持一致。

如果对象已启用 S3 存储桶密钥，则在复制或修改对象时，该对象的 S3 存储桶密钥设置不会更改。但是，如果您修改或复制未启用 S3 存储桶密钥的对象，并且目标存储桶具有 S3 存储桶密钥配置，则该对象将继承目标存储桶的 S3 存储桶密钥设置。例如，如果源对象尚未启用 S3 存储桶密钥，但目标存储桶已启用 S3 存储桶密钥，则为该对象启用 S3 存储桶密钥。

**在创建新存储桶时启用 S3 存储桶密钥**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在左侧导航窗格中，选择**存储桶**。

1. 请选择 **Create bucket（创建存储桶）**。

1. 输入存储桶名称，然后选择您的 AWS 区域。

1. 在**默认加密**下，对于**加密密钥类型**，选择 **AWS Key Management Service 密钥（SSE-KMS）**。

1. 在 **AWS KMS 密钥**下，执行以下操作以选择您的 KMS 密钥：
   + 要从可用的 KMS 密钥列表中进行选择，请选择**从您的 AWS KMS keys 中进行选择**，然后从可用密钥的列表中选择您的 **KMS 密钥**。

     AWS 托管式密钥（`aws/s3`）和您的客户自主管理型密钥都显示在此列表中。有关客户自主管理型密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[客户密钥和 AWS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#key-mgmt)。
   + 要输入 KMS 密钥 ARN，请选择**输入 AWS KMS key ARN**，然后在显示的字段中输入您的 KMS 密钥 ARN。
   + 要在 AWS KMS 控制台中创建新的客户自主管理型密钥，请选择**创建 KMS 密钥**。

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

1. 在 **Bucket Key（存储桶密钥）**下，请选择 **Enable（启用）**。

1. 请选择 **Create bucket（创建存储桶）**。

   Amazon S3 创建启用了 S3 存储桶密钥的存储桶。您上传到存储桶的新对象将使用 S3 存储桶密钥。 

   要禁用 S3 存储桶密钥，请按照前面的步骤操作，然后选择 **Disable（禁用）**。

**为现有存储桶启用 S3 存储桶密钥**

1. 通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在左侧导航窗格中，选择**存储桶**。

1. 在 **Buckets（存储桶）**列表中，请选择要为其启用 S3 存储桶密钥的存储桶。

1. 选择**属性**选项卡。

1. 在**默认加密**下，选择**编辑**。

1. 在**默认加密**下，对于**加密密钥类型**，选择 **AWS Key Management Service 密钥（SSE-KMS）**。

1. 在 **AWS KMS 密钥**下，执行以下操作以选择您的 KMS 密钥：
   + 要从可用的 KMS 密钥列表中进行选择，请选择**从您的 AWS KMS keys 中进行选择**，然后从可用密钥的列表中选择您的 **KMS 密钥**。

     AWS 托管式密钥（`aws/s3`）和您的客户自主管理型密钥都显示在此列表中。有关客户自主管理型密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[客户密钥和 AWS 密钥](https://docs.aws.amazon.com//kms/latest/developerguide/concepts.html#key-mgmt)。
   + 要输入 KMS 密钥 ARN，请选择**输入 AWS KMS key ARN**，然后在显示的字段中输入您的 KMS 密钥 ARN。
   + 要在 AWS KMS 控制台中创建新的客户自主管理型密钥，请选择**创建 KMS 密钥**。

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

1. 在 **Bucket Key（存储桶密钥）**下，请选择 **Enable（启用）**。

1. 选择 **Save Changes**（保存更改）。

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

   要禁用 S3 存储桶密钥，请按照前面的步骤操作，然后选择 **Disable（禁用）**。

## 使用 REST API
<a name="enable-bucket-key-rest"></a>

您可以使用 [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) 为存储桶启用或禁用 S3 存储桶密钥。要使用 `PutBucketEncryption` 配置 S3 存储桶密钥，请使用 [ServerSideEncryptionRule](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ServerSideEncryptionRule.html) 数据类型，其中包括使用 SSE-KMS 进行的默认加密。您还可以通过客户托管密钥的 KMS 密钥 ID 来选择使用客户托管密钥。  

有关更多信息和示例语法，请参阅 [ putbucKetenCryption ](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html)。

## 使用适用于 Java 的 AWS 软件开发工具包
<a name="enable-bucket-key-sdk"></a>

以下示例使用 适用于 Java 的 AWS SDK，通过 SSE-KMS 和 S3 存储桶密钥启用默认存储桶加密。

------
#### [ Java ]

```
AmazonS3 s3client = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.DEFAULT_REGION)
    .build();
    
ServerSideEncryptionByDefault serverSideEncryptionByDefault = new ServerSideEncryptionByDefault()
    .withSSEAlgorithm(SSEAlgorithm.KMS);
ServerSideEncryptionRule rule = new ServerSideEncryptionRule()
    .withApplyServerSideEncryptionByDefault(serverSideEncryptionByDefault)
    .withBucketKeyEnabled(true);
ServerSideEncryptionConfiguration serverSideEncryptionConfiguration =
    new ServerSideEncryptionConfiguration().withRules(Collections.singleton(rule));

SetBucketEncryptionRequest setBucketEncryptionRequest = new SetBucketEncryptionRequest()
    .withServerSideEncryptionConfiguration(serverSideEncryptionConfiguration)
    .withBucketName(bucketName);
            
s3client.setBucketEncryption(setBucketEncryptionRequest);
```

------

## 使用 AWS CLI
<a name="enable-bucket-key-cli"></a>

以下示例使用 AWS CLI，通过 SSE-KMS 和 S3 存储桶密钥启用默认存储桶加密。将 `user input placeholders` 替换为您自己的信息。

```
aws s3api put-bucket-encryption --bucket amzn-s3-demo-bucket --server-side-encryption-configuration '{
        "Rules": [
            {
                "ApplyServerSideEncryptionByDefault": {
                    "SSEAlgorithm": "aws:kms",
                    "KMSMasterKeyID": "KMS-Key-ARN"
                },
                "BucketKeyEnabled": true
            }
        ]
    }'
```

## 使用 CloudFormation
<a name="enable-bucket-key-cloudformation"></a>

有关使用 CloudFormation 配置 S3 存储桶密钥的更多信息，请参阅《AWS CloudFormation 用户指南》**中的 [AWS::S3::Bucket ServerSideEncryptionRule](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionrule.html)。

# 在对象级别配置 S3 存储桶密钥
<a name="configuring-bucket-key-object"></a>

当您使用 REST API、AWS SDK 或 AWS CLI 执行 PUT 或 COPY 操作时，您可以通过添加带有 `true` 或 `false` 值的 `x-amz-server-side-encryption-bucket-key-enabled` 请求标头在对象级别启用或禁用 S3 存储桶密钥。S3 存储桶密钥通过减少从 Amazon S3 到 AWS KMS 的请求流量，降低了使用 AWS Key Management Service（AWS KMS）（SSE-KMS）进行服务器端加密的成本。有关更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

当您使用 PUT 或 COPY 操作为对象配置 S3 存储桶密钥时，Amazon S3 仅更新该对象的设置。目标存储桶的 S3 存储桶密钥设置不会更改。如果您在启用了 S3 存储桶密钥的存储桶中提交对于 KMS 加密对象的 PUT 或 COPY 请求，则除非您禁用了请求标头中的密钥，否则您的对象级操作将自动使用 S3 存储桶密钥。如果您未为对象指定 S3 存储桶密钥，则 Amazon S3 会将目标存储桶的 S3 存储桶密钥设置应用于该对象。

**先决条件：**  
在将对象配置为使用 S3 存储桶密钥之前，请查看 [启用 S3 存储桶密钥之前需要注意的更改](bucket-key.md#bucket-key-changes)。

**Topics**
+ [

## Amazon S3 批量操作
](#bucket-key-object-bops)
+ [

## 使用 REST API
](#bucket-key-object-rest)
+ [

## 使用适用于 Java 的 AWS SDK（PutObject）
](#bucket-key-object-sdk)
+ [

## 使用 AWS CLI (PutObject)
](#bucket-key-object-cli)

## Amazon S3 批量操作
<a name="bucket-key-object-bops"></a>

要加密现有 Amazon S3 对象，可以使用 Amazon S3 批量操作。您为 S3 批量操作提供了要操作的对象列表，而批量操作调用相应的 API 来执行指定的操作。

您可以使用 [S3 批量操作复制操作](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-copy-object.html)复制现有的未加密对象，并将其作为加密对象写回同一存储桶。单个批量操作作业可对数十亿个对象执行指定操作。有关更多信息，请参阅 [使用批量操作批量执行对象操作](batch-ops.md) 和 [使用 Amazon S3 批量操作加密对象](https://aws.amazon.com/blogs/storage/encrypting-objects-with-amazon-s3-batch-operations/)。

## 使用 REST API
<a name="bucket-key-object-rest"></a>

使用 SSE-KMS 时，您可以使用以下 API 操作为对象启用 S3 存储桶密钥：
+ [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) – 上传对象时，您可以指定 `x-amz-server-side-encryption-bucket-key-enabled` 请求标头以在对象级别启用或禁用 S3 存储桶密钥。
+ [CopyObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) – 当您复制对象并配置 SSE-KMS 时，您可以指定 `x-amz-server-side-encryption-bucket-key-enabled` 请求标头以为对象启用或禁用 S3 存储桶密钥。
+ [POST 对象](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) – 当您使用 `POST` 操作上传对象并配置 SSE-KMS 时，您可以使用 `x-amz-server-side-encryption-bucket-key-enabled` 表单字段为对象启用或禁用 S3 存储桶密钥。
+ [CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) – 当您使用 `CreateMultipartUpload` API 操作上传大型对象并配置 SSE-KMS 时，您可以使用 `x-amz-server-side-encryption-bucket-key-enabled` 请求标头为对象启用或禁用 S3 存储桶密钥。

要在对象级别启用 S3 存储桶密钥，请包含 `x-amz-server-side-encryption-bucket-key-enabled` 请求标头。有关 SSE-KMS 和 REST API 的更多信息，请参阅 [使用 REST API](specifying-kms-encryption.md#KMSUsingRESTAPI)。

## 使用适用于 Java 的 AWS SDK（PutObject）
<a name="bucket-key-object-sdk"></a>

您可以使用以下示例通过 适用于 Java 的 AWS SDK 在对象级别配置 S3 存储桶密钥。

------
#### [ Java ]

```
AmazonS3 s3client = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.DEFAULT_REGION)
    .build();

String bucketName = "amzn-s3-demo-bucket1";
String keyName = "key name for object";
String contents = "file contents";

PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, keyName, contents)
    .withBucketKeyEnabled(true);
    
s3client.putObject(putObjectRequest);
```

------

## 使用 AWS CLI (PutObject)
<a name="bucket-key-object-cli"></a>

您可以使用以下 AWS CLI 示例作为 `PutObject` 请求的一部分在对象级别配置 S3 存储桶密钥。

```
aws s3api put-object --bucket amzn-s3-demo-bucket --key object key name --server-side-encryption aws:kms --bucket-key-enabled --body filepath
```

# 查看 S3 存储桶密钥的设置
<a name="viewing-bucket-key-settings"></a>

您可以使用 Amazon S3 控制台、REST API、AWS Command Line Interface（AWS CLI）或 AWS SDK 在存储桶或对象级别查看 S3 存储桶密钥的设置。

S3 存储桶密钥减少了从 Amazon S3 到 AWS KMS 的请求流量，从而降低了使用 AWS Key Management Service（SSE-KMS）进行服务器端加密的成本。有关更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

要查看存储桶或已从存储桶配置继承了 S3 存储桶密钥设置的对象的 S3 存储桶密钥设置，您需要获得执行 `s3:GetEncryptionConfiguration` 操作的权限。有关更多信息，请参阅 *Amazon Simple Storage Service API 参考*中的 [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html)。

## 使用 S3 控制台
<a name="bucket-key-settings"></a>

在 S3 控制台中，您可以查看存储桶或对象的 S3 存储桶密钥设置。S3 存储桶密钥设置继承自存储桶配置，除非源对象已配置 S3 存储桶密钥。

同一存储桶中的对象和文件夹可以具有不同的 S3 存储桶密钥设置。例如，如果您使用 REST API 上传对象并为该对象启用了 S3 存储桶密钥，则即使在目标存储桶中禁用了 S3 存储桶密钥，该对象仍会在目标存储桶中保留其 S3 存储桶密钥设置。另一个示例是，如果您为现有存储桶启用 S3 存储桶密钥，则存储桶中已存在的对象将不使用 S3 存储桶密钥。但是，新对象已启用 S3 存储桶密钥。

**查看存储桶的 S3 存储桶密钥设置**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在左侧导航窗格中，选择**存储桶**。

1. 在 **Buckets（存储桶）**列表中，请选择要为其启用 S3 存储桶密钥的存储桶。

1. 选择 **Properties (属性)**。

1. 在**默认加密**部分的**存储桶密钥**下，您可以看到存储桶的 S3 存储桶密钥设置。

   如果您看不到 S3 存储桶密钥设置，则可能没有执行 `s3:GetEncryptionConfiguration` 操作的权限。有关更多信息，请参阅 *Amazon Simple Storage Service API 参考* 中的 [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html)。

**查看对象的 S3 存储桶密钥设置**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在 **Buckets（存储桶）**列表中，请选择要为其启用 S3 存储桶密钥的存储桶。

1. 在 **Objects（对象）**列表中，请选择对象名称。

1. 在 **Details (详细信息)** 选项卡上，**Server-side encryption settings (服务器端加密设置)** 下，请选择 **Edit (编辑)**。

   在**存储桶密钥**下，您可以看到对象的 S3 存储桶密钥设置。您无法编辑此设置。

## 使用 AWS CLI
<a name="bucket-key-settings-cli"></a>

**返回存储桶级别 S3 存储桶密钥设置**  
要使用此示例，请将每个 `user input placeholder` 替换为您自己的信息。

```
aws s3api get-bucket-encryption --bucket amzn-s3-demo-bucket1
```

有关更多信息，请参阅《AWS CLI 命令参考》**中的 [get-bucket-encryption](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-encryption.html)。

**返回对象级别 S3 存储桶密钥设置**  
要使用此示例，请将每个 `user input placeholder` 替换为您自己的信息。

```
aws s3api head-object --bucket amzn-s3-demo-bucket1 --key my_images.tar.bz2
```

有关更多信息，请参阅《AWS CLI 命令参考》**中的 [head-object](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/head-object.html)。

## 使用 REST API
<a name="bucket-key-settings-rest"></a>

**返回存储桶级别 S3 存储桶密钥设置**  
要返回存储桶的加密信息，包括 S3 存储桶密钥的设置，请使用 `GetBucketEncryption` 操作。S3 存储桶密钥设置将在 `ServerSideEncryptionConfiguration` 元素中的响应正文中与 `BucketKeyEnabled` 设置一起返回。有关更多信息，请参阅 *Amazon S3 API 参考*中的 [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html)。

**返回 S3 存储桶密钥的对象级别设置**  
要返回对象的 S3 存储桶密钥状态，请使用 `HeadObject` 操作。`HeadObject` 返回 `x-amz-server-side-encryption-bucket-key-enabled` 响应标头，以显示是否为对象启用或禁用了 S3 存储桶密钥。有关更多信息，请参阅 *Amazon S3 API 参考*中的 [HeadObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html)。

如果为对象配置了 S3 存储桶密钥，则以下 API 操作还会返回 `x-amz-server-side-encryption-bucket-key-enabled` 响应标头：
+ [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) 
+ [PostObject](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.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) 
+ [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) 
+ [GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) 