

# Amazon S3 中的安全性
<a name="security"></a>

**重要**  
从 2026 年 4 月开始，AWS 将对所有新存储桶禁用具有客户提供密钥的服务器端加密（SSE-C）。此外，对于 AWS 账户中没有任何 SSE-C 加密数据的所有现有存储桶，都将禁用 SSE-C 加密。通过这些更改，少数需要 SSE-C 加密的应用程序必须在创建存储桶后，专门通过 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API 启用 SSE-C。在这些情况下，您可能需要更新自动化脚本、CloudFormation 模板或其他基础设施配置工具来配置这些设置。有关更多信息，请参阅 [AWS Storage 博客文章](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)。

AWS的云安全性的优先级最高。作为 AWS 客户，您将从专为满足大多数安全敏感型组织的要求而打造的数据中心和网络架构中受益。

安全性是 AWS 和您的共同责任。[责任共担模式](https://aws.amazon.com/compliance/shared-responsibility-model/)将其描述为云*本身*的安全性和云*中*的安全性：

**云的安全性**  
AWS 负责保护在 AWS 云 中运行 AWS 服务的基础设施。AWS 还向您提供可安全使用的服务。作为 [AWS 合规计划](https://aws.amazon.com/compliance/programs/)的一部分，我们的安全有效性会定期由第三方审核员进行测试和验证。要了解适用于 Amazon S3 的合规性计划，请参阅 [AWS 按合规性计划提供的范围内服务](https://aws.amazon.com/compliance/services-in-scope/)。

**云中的安全性**  
您的责任由您使用的 AWS 服务决定。您还需要对其他因素负责，包括您的数据的敏感性、您组织的要求以及适用的法律法规。对于 Amazon S3，您的责任包括以下各个方面：
+ 管理数据，包括[对象所有权](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)和[加密](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingEncryption.html)。
+ 对资产进行分类。
+ 使用 [IAM 角色](https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html#roles)[管理](https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-iam.html)您数据的访问权以及其他服务配置来应用适当的权限。
+ 启用侦测性控制，例如适用于 Amazon S3 的 [AWS CloudTrail](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cloudtrail-logging.html) 或 [Amazon GuardDuty](https://docs.aws.amazon.com/guardduty/latest/ug/s3_detection.html)。

此文档将帮助您了解如何在使用 Amazon S3 时应用责任共担模式。以下主题说明如何配置 Amazon S3 以实现您的安全性和合规性目标。您还将了解如何使用其他 AWS 服务来帮助您监控和保护您的 Amazon S3 资源。

**注意**  
有关将 Amazon S3 Express One Zone 存储类与目录存储桶配合使用的更多信息，请参阅 [S3 Express One Zone](directory-bucket-high-performance.md#s3-express-one-zone) 和[使用目录存储桶](directory-buckets-overview.md)。

**Topics**
+ [Amazon S3 的安全最佳实践](security-best-practices.md)
+ [Amazon S3 中的数据保护](DataDurability.md)
+ [利用加密来保护数据](UsingEncryption.md)
+ [互联网络流量隐私](inter-network-traffic-privacy.md)
+ [Amazon S3 的合规性验证](s3-compliance.md)
+ [Amazon S3 中的恢复能力](disaster-recovery-resiliency.md)
+ [Amazon S3 中的基础设施安全性](network-isolation.md)
+ [Amazon S3 中的配置和漏洞分析](vulnerability-analysis-and-management.md)
+ [访问权限管理](security-access-management.md)
+ [Amazon Simple Storage Service 数据清单](s3-data-inventory.md)

# Amazon S3 的安全最佳实践
<a name="security-best-practices"></a>

**重要**  
从 2026 年 4 月开始，AWS 将对所有新存储桶禁用具有客户提供密钥的服务器端加密（SSE-C）。此外，对于 AWS 账户中没有任何 SSE-C 加密数据的所有现有存储桶，都将禁用 SSE-C 加密。通过这些更改，少数需要 SSE-C 加密的应用程序必须在创建存储桶后，专门通过 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API 启用 SSE-C。在这些情况下，您可能需要更新自动化脚本、CloudFormation 模板或其他基础设施配置工具来配置这些设置。有关更多信息，请参阅 [AWS Storage 博客文章](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)。

Amazon S3 提供了在您开发和实施自己的安全策略时需要考虑的大量安全特征。以下最佳实操是一般准则，并不代表完整的安全解决方案。这些最佳实践可能不适合您的环境或不满足您的环境要求，请将其视为有用的建议而不是惯例。

**Topics**
+ [Amazon S3 安全最佳实践](#security-best-practices-prevent)
+ [Amazon S3 监控和审计最佳实践](#security-best-practices-detect)
+ [使用托管式 AWS 安全服务监控数据安全](#monitoring-data-security)

## Amazon S3 安全最佳实践
<a name="security-best-practices-prevent"></a>

Amazon S3 的以下最佳实践可以帮助预防安全事故。

**禁用访问控制列表（ACL)**  
S3 对象所有权是 Amazon S3 存储桶级别的设置，您可以使用该设置来控制上传到存储桶的对象的所有权和禁用或启用 ACL。默认情况下，对象所有权设为强制存储桶拥有者设置，并且所有 ACL 均处于禁用状态。禁用 ACL 后，存储桶拥有者拥有存储桶中的所有对象，并使用访问管理策略来专门管理对数据的访问权限。  
Amazon S3 中的大多数现代使用案例不再要求使用[访问控制列表（ACL）](acl-overview.md)。我们建议您禁用 ACL，除非有必须单独控制每个对象的访问权限的情况。要禁用 ACL 并获得存储桶中每个对象的所有权，请为 S3 对象所有权应用强制存储桶拥有者设置。禁用 ACL 时，您可以轻松通过不同的 AWS 账户 上传的对象维护存储桶。  
禁用 ACL 时，数据的访问控制基于策略，如下所示：  
+ AWS Identity and Access Management（IAM）用户策略
+ S3 存储桶策略
+ 虚拟私有云（VPC）端点策略
+ AWS Organizations 服务控制策略（SCP）
+ AWS Organizations 资源控制策略（RCP）
  
禁用 ACL 简化了权限管理和审计。对于新存储桶，默认情况下 ACL 处于禁用状态。您还可以对现有存储桶禁用 ACL。如果现有存储桶中已有对象，在禁用 ACL 后，对象和存储桶 ACL 将不再是访问评估过程的一部分。相反，将根据策略授予或拒绝访问权限。  
在禁用 ACL 之前，请确保执行以下操作：  
+ 查看存储桶策略，以确保此策略涵盖了您打算在账户外授予对存储桶的访问权限的所有方式。
+ 将存储桶 ACL 重置为默认（由存储桶拥有者完全控制）。
  
禁用 ACL 后，会出现以下行为：  
+ 您的存储桶仅接受未指定 ACL 的 `PUT` 请求或指定了存储桶拥有者完全控制的 ACL 的 `PUT` 请求。这些 ACL 包括 `bucket-owner-full-control` 标准 ACL 或以 XML 表示的此 ACL 的等效形式。
+ 支持存储桶拥有者完全控制 ACL 的现有应用程序没有影响。
+ 包含其他 ACL 的 `PUT` 请求（例如，向某些 AWS 账户 进行自定义授权）将失败并返回 HTTP 状态代码 `400 (Bad Request)`，和错误代码 `AccessControlListNotSupported`。
   
有关更多信息，请参阅 [为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。

**确保您的 Amazon S3 存储桶使用正确的策略且不可公有访问**  
除非您明确要求互联网上的任何人都能读写您的 S3 存储桶，否则请确保 S3 存储桶不是公有的。以下是您可以采取的屏蔽公共访问权限的一些步骤：  
+ 使用 S3 屏蔽公共访问权限。借助 S3 屏蔽公共访问权限，您可以轻松地设置集中控制，以限制对 Amazon S3 资源的公共访问。无论资源是如何创建的，都会实施这些集中控制。对于管理多个 AWS 账户的组织，您现在可以通过 AWS Organizations 使用组织级别的强制措施，采用单策略配置来集中管理整个组织中的 S3 屏蔽公共访问权限设置。

  有关更多信息，请参阅 [阻止对您的 Amazon S3 存储的公有访问](access-control-block-public-access.md)。
+ 找出允许使用通配符身份的 Amazon S3 存储桶策略，例如 `"Principal": "*"`（这实际上意味着“任何人”）。还要找出允许通配符操作 `"*"` 的策略（这实际上允许用户在 Amazon S3 存储桶中执行任何操作）。
+ 类似地，找出向“任何人”或者“任何经过身份验证的 AWS 用户”提供读、写或完全访问权限的 Amazon S3 存储桶访问控制列表（ACL）。
+ 使用 `ListBuckets` API 操作扫描所有 Amazon S3 存储桶。然后，使用 `GetBucketAcl`、`GetBucketWebsite` 和 `GetBucketPolicy` 确定每个存储桶是否拥有符合要求的访问控制和符合要求的配置。
+ 使用 [AWS Trusted Advisor](https://docs.aws.amazon.com/awssupport/latest/user/getting-started.html#trusted-advisor) 检查您的 Amazon S3 实现。
+ 考虑使用 [https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-public-read-prohibited.html](https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-public-read-prohibited.html) 和 [https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-public-write-prohibited.html](https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-public-write-prohibited.html) 托管式 AWS Config 规则 来实施持续的侦测性控制。
**对于具有多个 AWS 账户的组织，可以考虑使用组织级别的屏蔽公共访问权限管理措施：**  
+ 集中式策略管理：使用 AWS Organizations 创建单个 S3 屏蔽公共访问权限策略，该策略会自动应用到所有成员账户或选定的组织单元（OU）。
+ 自动继承：当您在根级别或 OU 级别附加策略时，新成员账户可自动继承屏蔽公共访问权限设置，无需单独设置账户。
+ 简化合规性：使用组织级别策略时，无需维护复杂的服务控制策略（SCP）来实施屏蔽公共访问权限，并减少了管理账户各个配置的运营开销。
+ 审计功能：使用 AWS CloudTrail 监控各个成员账户上的策略附加和执行情况，以进行合规性跟踪。
有关更多信息，请参阅 [Amazon S3 的身份和访问管理](security-iam.md)。

**对存储桶禁用具有客户提供密钥的服务器端加密（SSE-C）**  
Amazon S3 中的大多数现代化使用案例不再使用 SSE-C，因为相比具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）或具有 AWS KMS 密钥的服务器端加密（SSE-KMS），这种方法欠缺灵活性。SSE-C 要求您在每次与 SSE-C 加密数据交互时提供加密密钥，因此您无法通过与其他用户、角色或 AWS 服务共享 SSE-C 密钥来允许对方从您的 S3 存储桶读取数据以便操作数据。  
要限制可在通用存储桶中使用的服务器端加密类型，您可以选择更新存储桶的默认加密配置，以此来阻止 SSE-C 写入请求。此存储桶级别的配置将阻止请求上传指定了 SSE-C 的对象。当存储桶阻止 SSE-C 时，任何指定了 SSE-C 加密的 `PutObject`、`CopyObject`、`PostObject`、分段上传或复制请求都将被拒绝，并返回 `HTTP 403 AccessDenied` 错误。  
要了解有关阻止 SSE-C 的更多信息，请参阅[对通用存储桶阻止或取消阻止 SSE-C](blocking-unblocking-s3-c-encryption-gpb.md)。

**在您的账户区域命名空间中创建存储桶**  
默认情况下，您在共享全局命名空间中创建全局通用存储桶。在共享全局命名空间中创建通用存储桶后，其他任何人均无法在分区内创建该存储桶名称。当您删除全局通用存储桶时，该存储桶名称将在全局命名空间中再次变为可用，供任何人重新创建。  
尽管 Amazon S3 通用存储桶存在于共享全局命名空间中，但您可以选择在账户区域命名空间中创建存储桶。账户区域命名空间是全局存储桶命名空间的保留细分，只有您的账户才能在其中创建通用存储桶。我们建议您在账户区域命名空间中创建存储桶，因为这些存储桶对于您的账户是唯一的，并且始终无法由其它账户重新创建。有关更多信息，请参阅 [通用存储桶的命名空间](gpbucketnamespaces.md)。  
我们建议您不要删除共享全局命名空间中的全局通用存储桶。现在，所有 AWS 账户都有 10000 个存储桶的默认存储桶配额，因此无需从您的账户中删除空存储桶。如果您删除共享全局命名空间中的存储桶，请注意，同一分区中的另一个 AWS 账户可以使用相同的存储桶名称来表示新的存储桶，因此可能会收到针对已删除的存储桶的请求。如果需要防止出现这种情况，或者如果您希望继续使用相同的存储桶名称，请不要删除该存储桶。我们建议您，清空并保留存储桶。可根据需要阻止任何存储桶请求，而不是删除存储桶。对于不再活跃使用的存储桶，我们建议清空存储桶中的所有对象，以最大限度地降低成本，同时保留存储桶本身。有关更多信息，请参阅 [删除通用存储桶](delete-bucket.md)。

**实施最低权限访问**  
在授予权限时，您可以决定谁获得哪些 Amazon S3 资源的哪些权限。您可以对这些资源启用希望允许的特定操作。因此，我们建议您仅授予执行任务所需的权限。实施最低权限访问对于减小安全风险以及可能由错误或恶意意图造成的影响至关重要。  
为实现最低权限访问，可以使用以下工具：  
+ [Amazon S3 的策略操作](security_iam_service-with-iam.md#security_iam_service-with-iam-id-based-policies-actions) 和 [IAM 实体的权限边界](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html)
+ [Amazon S3 如何与 IAM 配合使用](security_iam_service-with-iam.md)
+ [访问控制列表 (ACL) 概述](acl-overview.md)
有关选择一个或多个前述机制时所要考虑的事项的指南，请参阅 [Amazon S3 的身份和访问管理](security-iam.md)。

**将 IAM 角色用于需要 Amazon S3 访问权限的应用程序和 AWS 服务**  
为了使在 Amazon EC2 或其他 AWS 服务上运行的应用程序能够访问 Amazon S3 资源，应用程序必须在其 AWS API 请求中包含有效的 AWS 凭证。我们建议您不要直接在应用程序或 Amazon EC2 实例中存储 AWS 凭证，这些是不会自动轮换的长期凭证，如果它们受到损害，可能会对业务产生重大影响。  
而是使用 IAM 角色来管理需要访问 Amazon S3 的应用程序或服务的临时凭证。在使用角色时，您不需要将长期凭证（如用户名和密码或访问密钥）分配给 Amazon EC2 实例或 AWS 服务（例如 AWS Lambda）。角色可提供临时权限供应用程序在调用其他 AWS 资源时使用。  
有关更多信息，请参阅 *IAM 用户指南*中的以下主题：  
+ [IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)
+ [针对角色的常见情形：用户、应用程序和服务](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios.html)

  

**考虑加密静态数据**  
您可以通过以下选项在 Amazon S3 中保护静态数据：  
+ **服务器端加密** – 默认情况下，所有 Amazon S3 存储桶都配置了加密，所有上传到 S3 存储桶的新对象都会自动静态加密。具有 Amazon S3 托管密钥的服务器端加密（SSE-S3）是 Amazon S3 中每个存储桶的默认加密配置。要使用其他类型的加密，您可以指定要在 S3 `PUT` 请求中使用的服务器端加密类型，也可以在目标存储桶中设置默认加密配置。

  Amazon S3 也提供了以下服务器端加密选项：
  + 具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS） 
  + 具有 AWS Key Management Service（AWS KMS）密钥的双层服务器端加密（DSSE-KMS）
  + 具有客户提供密钥的服务器端加密（SSE-C）

  有关更多信息，请参阅 [使用服务器端加密保护数据](serv-side-encryption.md)。
+ **客户端加密** – 在客户端加密数据并将加密的数据上传到 Amazon S3。在这种情况下，您需要管理加密过程、加密密钥和相关的工具。如服务器端加密一样，客户端加密可以帮助减少面临的风险：通过使用存储在一个不同机制（而不是存储数据本身的机制）中的密钥来加密数据。

  Amazon S3 提供多个客户端加密选项。有关更多信息，请参阅 [使用客户端加密保护数据](UsingClientSideEncryption.md)。

**实施传输中数据加密**  
您可以使用 HTTPS（TLS）帮助防止潜在攻击者使用中间人攻击或类似攻击来窃听或操纵网络流量。我们建议通过在 Amazon S3 存储桶策略中使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Boolean](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Boolean) 条件，以只允许通过 HTTPS（TLS）的加密连接。有关更多信息，请参阅示例 S3 存储桶策略[管理基于 HTTP 或 HTTPS 请求的访问权限](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-HTTP-HTTPS)。除了拒绝 HTTP 请求外，我们还建议您对 `tlsDetails.tlsVersion NOT EXISTS` 设置 Amazon CloudWatch 警报，以便在有人尝试对您的内容进行 HTTP 访问时提醒您。有关如何配置 Amazon CloudWatch 警报的更多信息，请参阅《AWS CloudTrail User Guide》**中的 [Creating CloudWatch alarms for CloudTrail events: examples](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html) 和 [CloudTrail record contents](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html)。  
我们建议您的应用程序不要固定 Amazon S3 TLS 证书，因为 AWS 不支持固定公开信任的证书。S3 会自动续订证书，而续订可能在证书到期之前的任何时候发生。续订证书会生成新的公有-私有密钥对。如果您固定了最近使用新公钥续订的 S3 证书，则在您的应用程序使用新证书之前，您将无法连接到 S3。
也可以考虑使用 [https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-ssl-requests-only.html](https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-ssl-requests-only.html) 托管式 AWS Config 规则来实施持续的侦测性控制。

**考虑使用 S3 对象锁定**  
借助 S3 对象锁定，您可以使用“一次写入，多次读取”（WORM）模式存储对象。S3 对象锁定可以帮助阻止意外或不当删除数据。例如，您可以使用 S3 对象锁定来帮助保护您的 AWS CloudTrail 日志。  
有关更多信息，请参阅 [使用对象锁定以锁定对象](object-lock.md)。

**启用 S3 版本控制**  
S3 版本控制是在相同的存储桶中保留对象的多个版本的方法。对于 存储桶中存储的每个对象，您可以使用版本控制功能来保留、检索和还原它们的各个版本。使用版本控制能够轻松从用户意外操作和应用程序故障中恢复数据。  
也可以考虑使用 [https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-versioning-enabled.html](https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-versioning-enabled.html) 托管式 AWS Config 规则来实施持续的侦测性控制。  
有关更多信息，请参阅 [使用 S3 版本控制保留对象的多个版本](Versioning.md)。

**考虑使用 Amazon S3 跨区域复制**  
虽然 Amazon S3 在默认情况下跨多个地理位置不同的可用区存储数据，但合规性要求所规定的数据存储距离可能更远。通过 S3 跨区域复制（CRR），可以在远距离 AWS 区域之间复制数据以帮助满足这些要求。CRR 允许在不同 AWS 区域 中的存储桶之间自动以异步方式复制对象。有关更多信息，请参阅 [在区域内和跨区域复制对象](replication.md)。  
CRR 要求源和目标 S3 存储桶都已启用版本控制。
也可以考虑使用 [https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-replication-enabled.html](https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-replication-enabled.html) 托管式 AWS Config 规则来实施持续的侦测性控制。

**考虑使用 VPC 端点进行 Amazon S3 访问**  
Amazon S3 的 Virtual Private Cloud（VPC）端点是 VPC 内的逻辑实体，仅允许连接到 Amazon S3。VPC 端点可以帮助防止流量穿越开放的互联网。  
Amazon S3 的 VPC 端点提供多种方式来控制对 Amazon S3 数据的访问：  
+ 通过使用 S3 存储桶策略，您可以控制允许通过特定 VPC 端点进行访问的请求、用户或组。
+ 可以使用 S3 存储桶策略控制哪些 VPC 或 VPC 端点有权访问 S3 存储桶。
+ 您可以使用没有 Internet 网关的 VPC 来阻止数据泄露。
有关更多信息，请参阅 [使用存储桶策略控制从 VPC 端点的访问](example-bucket-policies-vpc-endpoint.md)。

** 使用托管式 AWS 安全服务监控数据安全**  
多项托管式 AWS 安全服务可以帮助您识别、评测和监控 Amazon S3 数据的安全和合规风险。这些服务还可以帮助您保护数据免受这些风险的影响。这些服务包括自动检测、监控和保护功能，旨在从单个 AWS 账户的 Amazon S3 资源扩展到跨数千个账户的多个组织的资源。  
有关更多信息，请参阅 [使用托管式 AWS 安全服务监控数据安全](#monitoring-data-security)。

## Amazon S3 监控和审计最佳实践
<a name="security-best-practices-detect"></a>

Amazon S3 的以下最佳实践可以帮助检测潜在的安全弱点和事故。

**识别和审计您的所有 Amazon S3 存储桶**  
确定您的 IT 资产是监管和安全性的一个至关重要的方面。您需要了解您所有的 Amazon S3 资源，以评估它们的安全态势并对潜在的薄弱领域采取措施。要审计您的资源，我们建议您执行以下操作：  
+ 使用标签编辑器确定和标记安全敏感性或审计敏感性资源，然后在您需要搜索这些资源时使用这些标签。有关更多信息，请参阅《标记 AWS 资源用户指南》**中的[搜索要标记的资源](https://docs.aws.amazon.com/ARG/latest/userguide/tag-editor.html)。
+ 出于业务、合规性和法规要求，使用 S3 清单来审计和报告对象的复制和加密状态。有关更多信息，请参阅 [使用 S3 清单对数据进行编目和分析](storage-inventory.md)。
+ 为您的 Amazon S3 资源创建资源组。有关更多信息，请参阅《AWS Resource Groups 用户指南》**中的[什么是 Resource Groups？](https://docs.aws.amazon.com/ARG/latest/userguide/welcome.html)。

**使用 AWS 监控工具实施监控**  
监控是保持 Amazon S3 和您的 AWS 解决方案的可靠性、安全性、可用性和性能的重要部分。AWS 提供了一些可用来监控 Amazon S3 和您的其他 AWS 服务的工具和服务。例如，您可以监控 Amazon S3 的 Amazon CloudWatch 指标，特别是 `PutRequests`、`GetRequests`、`4xxErrors` 和 `DeleteRequests` 指标。有关更多信息，请参阅[使用 Amazon CloudWatch 监控指标](cloudwatch-monitoring.md)和[Amazon S3 中的日志记录和监控](monitoring-overview.md)。  
有关另一个示例，请参阅[示例：Amazon S3 存储桶活动](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudwatch-alarms-for-cloudtrail.html#cloudwatch-alarms-for-cloudtrail-s3-bucket-activity)。此示例介绍如何创建 CloudWatch 警报，当执行 Amazon S3 API 调用以 `PUT` 或 `DELETE` 存储桶策略、存储桶生命周期、存储桶复制配置时，或者 `PUT` 存储桶 ACL 时，会触发此警报。

**启用 Amazon S3 服务器访问日志记录**  
服务器访问日志记录详细地记录对存储桶提出的各种请求。服务器访问日志可以在安全和访问审计方面为您提供帮助，帮您了解您的客户群和了解您的 Amazon S3 账单。有关启用服务器访问日志记录的说明，请参阅 [使用服务器访问日志记录来记录请求](ServerLogs.md)。  
也可以考虑使用 [https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-logging-enabled.html](https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-logging-enabled.html) AWS Config 托管式规则来实施持续的侦测性控制。

**使用 AWS CloudTrail。**  
AWS CloudTrail 提供用户、角色或 AWS 服务在 Amazon S3 中执行的操作的记录。您可以使用 CloudTrail 收集的信息确定以下事项：  
+ 向 Amazon S3 发出的请求
+ 发出请求的 IP 地址
+ 谁发出了请求
+ 发出请求的时间
+ 有关该请求的其他详细信息
  
例如，您可以确定影响数据访问的 `PUT` 操作的 CloudTrail 条目，尤其是 `PutBucketAcl`、`PutObjectAcl`、`PutBucketPolicy` 和 `PutBucketWebsite`。  
当您设置 AWS 账户时，默认情况下 CloudTrail 处于启用状态。您可以在 CloudTrail 控制台中查看最近的事件。要为 Amazon S3 存储桶创建活动和事件的持续记录，您可以在 CloudTrail 控制台中创建跟踪。有关更多信息，请参阅《AWS CloudTrail 用户指南》**中的[记录数据事件](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html)。  
创建跟踪时，可以配置 CloudTrail 以记录数据事件。数据事件是在资源上或在资源内执行的资源操作的记录。在 Amazon S3 中，数据事件记录单个存储桶的对象级 API 活动。CloudTrail 支持 Amazon S3 对象级 API 操作的子集，例如 `GetObject`、`DeleteObject` 和 `PutObject`。有关 CloudTrail 如何与 Amazon S3 配合使用的更多信息，请参阅 [使用 AWS CloudTrail 记录 Amazon S3 API 调用](cloudtrail-logging.md)。在 Amazon S3 控制台中，您还可以将 S3 存储桶配置为 [为 S3 存储桶和对象启用 CloudTrail 事件日志记录](enable-cloudtrail-logging-for-s3.md)。  
AWS Config 提供了托管规则（`cloudtrail-s3-dataevents-enabled`），您可以使用该规则来确认至少有一个 CloudTrail 跟踪正在记录 S3 存储桶的数据事件。有关更多信息，请参阅 *AWS Config 开发人员指南*中的 [https://docs.aws.amazon.com//config/latest/developerguide/cloudtrail-s3-dataevents-enabled.html](https://docs.aws.amazon.com//config/latest/developerguide/cloudtrail-s3-dataevents-enabled.html)。

**启用 AWS Config**  
此主题中列出的几个最佳实践建议创建 AWS Config 规则。AWS Config 有助于评测、审计和评价您的 AWS 资源的配置。AWS Config 监控资源配置，以便您能够针对需要的安全配置评估所记录的配置。利用 AWS Config，您可以：  
+ 查看 AWS 资源之间的配置和关系的更改
+ 调查详细的资源配置历史记录
+ 根据内部指南中指定的配置确定总体合规性
  
使用 AWS Config 可帮助您简化合规性审核、安全性分析、变更管理和操作故障排除。有关更多信息，请参阅 *AWS Config 开发人员指南*中的[使用控制台设置 AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/gs-console.html)。当指定要记录的资源类型时，确保您包括了 Amazon S3 资源。  
在评估 Amazon S3 资源时，AWS Config 托管式规则仅支持通用存储桶。AWS Config 不记录目录存储桶的配置更改。有关更多信息，请参阅《AWS Config 开发人员指南》**中的 [AWS Config 托管式规则](https://docs.aws.amazon.com//config/latest/developerguide/evaluate-config_use-managed-rules.html)和 [AWS Config 托管式规则列表](https://docs.aws.amazon.com//config/latest/developerguide/managed-rules-by-aws-config.html)。
有关如何使用 AWS Config 的示例，请参阅《AWS 安全博客》**上的[如何使用 AWS Config 来监控和响应允许公共访问的 Amazon S3 存储桶](https://aws.amazon.com/blogs/security/how-to-use-aws-config-to-monitor-for-and-respond-to-amazon-s3-buckets-allowing-public-access/)。

**使用 S3 Storage Lens 存储统计管理工具**  
S3 Storage Lens 存储统计管理工具是一项云存储分析功能，您可以使用它在整个组织范围内了解对象存储的使用情况和活动。S3 Storage Lens 存储统计管理工具还分析指标以提供上下文建议，您可以使用这些建议来优化存储成本并应用最佳实践来保护数据。  
通过 S3 Storage Lens 存储统计管理工具，您可以使用指标生成摘要见解，例如，了解整个组织中有多少存储空间，或增长最快的存储桶和前缀是哪些。您还可以使用 S3 Storage Lens 存储统计管理工具指标来识别成本优化机会，实施数据保护和访问管理最佳实践，并提高应用程序工作负载的性能。  
例如，您可以识别没有 S3 生命周期规则的存储桶，以中止超过 7 天的未完成分段上传。您还可以识别未遵循数据保护最佳实践（例如使用 S3 复制或 S3 版本控制）的存储桶。有关更多信息，请参阅[了解 Amazon S3 Storage Lens](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage_lens_basics_metrics_recommendations.html)。

**监控 AWS 安全公告**  
我们建议您经常为您的 AWS 账户检查在 Trusted Advisor 中发布的安全公告。尤其要关注有关具有“开放访问权限”的 Amazon S3 存储桶的警告。您可以使用 [https://docs.aws.amazon.com/cli/latest/reference/support/describe-trusted-advisor-checks.html](https://docs.aws.amazon.com/cli/latest/reference/support/describe-trusted-advisor-checks.html) 通过编程方式来实现这一点。  
此外，积极地监控向您的每一个 AWS 账户注册的原始电子邮件地址。AWS 将使用该电子邮件地址就可能影响您的紧急安全事件与您联系。  
具有广泛影响的 AWS 操作性问题将在 [AWS Health Dashboard 服务运行状况](https://status.aws.amazon.com/)上发布。操作性问题也通过 AWS Health Dashboard 发布到各个账户。有关更多信息，请参阅 [AWS Health 文档](https://docs.aws.amazon.com/health/)。

## 使用托管式 AWS 安全服务监控数据安全
<a name="monitoring-data-security"></a>

多项托管式 AWS 安全服务可以帮助您识别、评测和监控 Amazon S3 数据的安全和合规风险。这些服务还可以帮助您保护数据免受这些风险的影响。这些服务包括自动检测、监控和保护功能，旨在从单个 AWS 账户的 Amazon S3 资源扩展到跨数千个 AWS 账户的多个组织的资源。

AWS 检测和响应服务可以帮助您识别潜在的安全配置错误、威胁或意外行为，以便您可以快速响应环境中潜在未经授权或恶意的活动。AWS 数据保护服务可以帮助您监控和保护您的数据、账户和工作负载，使其免受未经授权的访问。这些服务还有助于您发现 Amazon S3 数据资产中的敏感数据 [如个人身份信息（PII）]。

为帮助您识别和评估数据安全与合规性风险，托管式 AWS 安全服务会生成调查发现，以告知您与 Amazon S3 数据有关的潜在安全事件或问题。调查发现提供相关详细信息，您可以使用这些信息，根据事件/响应工作流和策略对这些风险进行调查、评测并采取措施。您可以使用每项服务直接访问调查发现数据。还可以将数据发送到其他应用程序、服务和系统，例如安全事故和事件管理系统（SIEM）。

要监控 Amazon S3 数据的安全性，请考虑使用以下这些托管式 AWS 安全服务。

**Amazon GuardDuty**  
Amazon GuardDuty 是一项威胁检测服务，可持续监控您的 AWS 账户和工作负载中是否存在恶意活动，并提供详细的安全调查发现以供查看和补救。  
使用 GuardDuty 中的 S3 保护特征，您可以配置 GuardDuty 来分析 Amazon S3 资源的 AWS CloudTrail 管理和数据事件。然后，GuardDuty 会监控这些事件中是否存在恶意和可疑活动。为了为分析提供信息并识别潜在的安全风险，GuardDuty 使用威胁情报源和机器学习。  
GuardDuty 可以监控 Amazon S3 资源的不同类型的活动。例如，Amazon S3 的 CloudTrail 管理事件包括存储桶级别的操作，例如 `ListBuckets`、`DeleteBucket` 和 `PutBucketReplication`。Amazon S3 的 CloudTrail 数据事件包括对象级操作，例如 `GetObject`、`ListObjects` 和 `PutObject`。如果 GuardDuty 检测到异常或潜在恶意的活动，它会生成调查发现来通知您。  
有关更多信息，请参阅《Amazon GuardDuty 用户指南》**中的 [Amazon GuardDuty 中的 Amazon S3 保护](https://docs.aws.amazon.com/guardduty/latest/ug/s3-protection.html)。

**Amazon Detective**  
Amazon Detective 简化了调查流程，并帮助您进行更快、更有效的安全调查。Detective 提供预构建的数据聚合、摘要和上下文，可以帮助您分析和评测可能的安全问题的性质和程度。  
Detective 会自动提取基于时间的事件，例如来自 AWS CloudTrail 的 API 调用和您的 AWS 资源的 Amazon VPC 流日志。它还采集 Amazon GuardDuty 生成的调查发现。然后，Detective 使用机器学习、统计分析和图形理论生成可视化效果，以帮助您更快地进行有效的安全调查。  
这些可视化效果提供了统一的交互式视图，可供您了解资源行为及此类行为随时间推移的相互作用。您可以浏览此行为图以检查潜在的恶意操作，例如登录尝试失败或可疑的 API 调用。您还可以查看这些操作如何影响资源（如 S3 存储桶和对象）。  
有关更多信息，请参阅[《Amazon Detective 管理指南》](https://docs.aws.amazon.com/detective/latest/adminguide/what-is-detective.html)。

**IAM Access Analyzer**  
AWS Identity and Access Management Access Analyzer（IAM Access Analyzer）可帮助您识别与外部实体共享的资源。还可以使用 IAM Access Analyzer 根据策略语法和最佳实践验证 IAM 策略，并根据 AWS CloudTrail 日志中的访问活动生成 IAM 策略。  
IAM Access Analyzer 使用基于逻辑的推理来分析 AWS 环境中的资源策略，例如存储桶策略。借助适用于 S3 的 IAM Access Analyzer，当 S3 存储桶配置为允许互联网上的任何人或其他 AWS 账户（包括组织外部的账户）访问时，将向您发出提醒。例如，适用于 S3 的 IAM Access Analyzer 可能会报告存储桶具有通过存储桶访问控制列表（ACL）、存储桶策略、多区域接入点策略或接入点策略提供的读取或写入访问权限。您会收到每个公共存储桶或共享存储桶的调查发现，其中指出了公共或共享访问的来源和级别。有了这些调查发现，您就可以立即采取精确的纠正措施，将存储桶访问权限恢复为您期望的设置。  
有关更多信息，请参阅 [使用适用于 S3 的 IAM Access Analyzer 查看存储桶访问权限](access-analyzer.md)。

**Amazon Macie**  
Amazon Macie 是一项安全服务，旨在使用机器学习和模式匹配来发现敏感数据。Macie 提供对数据安全风险的可见性，并实现针对这些风险的自动防护。借助 Macie，您可以自动发现和报告 Amazon S3 数据资产中的敏感数据，以更好地了解组织在 S3 中存储的数据。  
要使用 Macie 检测敏感数据，您可以使用内置标准和技术，这些标准和技术旨在检测许多国家和地区的大量且不断增长的敏感数据类型列表。这些敏感数据类型包括多种类型的个人身份信息（PII）、财务数据和凭证数据。您还可以使用自己定义的自定义标准：旨在定义要匹配的文本模式的正则表达式，以及（可选）用于优化结果的字符序列和邻近规则。  
如果 Macie 在 S3 对象中检测到敏感数据，Macie 会生成安全调查发现来通知您。此调查发现提供有关受影响的对象、Macie 发现的敏感数据的类型和出现次数的信息，以及其他详细信息，以帮助您调查受影响的 S3 存储桶和对象。有关更多信息，请参阅[《Amazon Macie 用户指南》](https://docs.aws.amazon.com/macie/latest/user/what-is-macie.html)。

**AWS Security Hub CSPM**  
AWS Security Hub CSPM 是一项安全态势管理服务，该服务可执行安全最佳实践检查，将来自多个来源的警报和调查发现聚合为单一格式，并支持自动补救。  
Security Hub CSPM 从集成的 AWS Partner Network安全解决方案和 AWS 服务（包括 Amazon Detective、Amazon GuardDuty、IAM Access Analyzer 和 Amazon Macie）收集并提供安全方面的调查发现数据。Security Hub 还可以根据 AWS 最佳实践和支持的行业标准运行持续的自动化安全检查，从而生成自己的调查发现。  
然后，Security Hub CSPM 关联并整合各提供方的调查发现，以帮助确定调查发现的优先级并处理最重要的调查发现。它还为自定义操作提供支持，您可以使用自定义操作来为特定类别的调查发现调用响应或补救操作。  
使用 Security Hub CSPM，您可以评测 Amazon S3 资源的安全性和合规性状态，也可以将其作为对组织在单个 AWS 区域和跨多个区域的安全状况进行更广泛分析的一部分。这包括分析安全趋势和确定优先级最高的安全问题。您还可以聚合来自多个 AWS 区域的调查发现，并监控和处理来自单个区域的聚合调查发现数据。  
有关更多信息，请参阅《AWS Security Hub CSPM 用户指南》**中的 [Amazon Simple Storage Service 控制](https://docs.aws.amazon.com/securityhub/latest/userguide/s3-controls.html)。

# Amazon S3 中的数据保护
<a name="DataDurability"></a>

Amazon S3 为任务关键型和主要数据存储提供了高度持久的存储基础设施。S3 Standard、S3 Intelligent-Tiering、S3 Standard-IA、S3 Glacier Instant Retrieval、S3 Glacier Flexible Retrieval、S3 Glacier Deep Archive 在 AWS 区域 中至少三个可用区的多个设备上冗余存储对象。可用区是 AWS 区域 中一个或多个具有冗余电源、网络和连接的离散数据中心。可用区与任何其他可用区之间有意义的距离（许多公里数）在物理上隔开，尽管所有可用区之间的距离都在 100 公里（60 英里）以内。S3 One Zone-IA 存储类将数据冗余存储在单个可用区中的多个设备上。这些服务旨在通过快速检测和修复任何丢失的冗余来处理并发设备故障，还可以使用校验和定期验证数据的完整性。

Amazon S3 standard 存储提供以下特征：
+ 以 [Amazon S3 服务等级协议](https://aws.amazon.com/s3/sla/)作为后盾
+ 设计目的是在指定年度内为对象提供 99.999999999% 的持久性和 99.99% 的可用性
+ S3 Standard、S3 Intelligent-Tiering、S3 Standard-IA、S3 Glacier Instant Retrieval、S3 Glacier Flexible Retrieval 和 S3 Glacier Deep Archive 都是为了在整个 Amazon S3 可用区丢失的情况下维持数据。

Amazon S3 使用版本控制功能进一步保护您的数据。对于 Amazon S3 存储桶中存储的每个对象，您可以使用版本控制功能来保存、检索和还原它们的每个版本。使用版本控制能够轻松从用户意外操作和应用程序故障中恢复数据。默认情况下，请求会检索最新写入的版本。您可以通过指定请求中对象的版本，来检索该对象的旧版本。

除了 S3 版本控制之外，您还可以使用 Amazon S3 对象锁定和 S3 复制来保护您的数据。有关更多信息，请参阅 [Amazon S3 中的数据保护](data-protection.md)。

出于数据保护的目的，我们建议您保护 AWS 账户凭证并使用 AWS Identity and Access Management 设置单个用户账户，以便仅向每个用户提供履行其工作职责所需的权限。

如果在通过命令行界面或 API 访问 AWS 时需要经过 FIPS 140-2 验证的加密模块，请使用 FIPS 端点。有关可用的 FIPS 端点的更多信息，请参阅[《美国联邦信息处理标准 (FIPS) 第 140-2 版》](https://aws.amazon.com/compliance/fips/)。

下面的安全最佳实践也探讨 Amazon S3 中的数据保护：
+ [Implement server-side encryption](security-best-practices.md#server-side)
+ [Enforce encryption of data in transit](security-best-practices.md#transit)
+ [Consider using Macie with Amazon S3](security-best-practices.md#macie)
+ [Identify and audit all your Amazon S3 buckets](security-best-practices.md#audit)
+ [Monitor Amazon Web Services security advisories](security-best-practices.md#advisories)

# 利用加密来保护数据
<a name="UsingEncryption"></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 数据中心的磁盘上时）期间保护数据。您可以使用安全套接字层/传输层安全性（SSL/TLS），包括混合后量子密钥交换或客户端加密来保护传输中数据。为保护 Amazon S3 中的静态数据，您具有以下选项：
+ **服务器端加密** – Amazon S3 在将对象保存到 AWS 数据中心的磁盘之前对其进行加密，然后在下载对象时对其进行解密。

  默认情况下，所有 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/)。

  有关服务器端加密的每个选项的更多信息，请参阅[使用服务器端加密保护数据](serv-side-encryption.md)。

  要配置服务器端加密，请参阅：
  + [指定具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）](specifying-s3-encryption.md)
  + [使用 AWS KMS (SSE-KMS) 指定服务器端加密](specifying-kms-encryption.md)
  + [指定具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）](specifying-dsse-encryption.md)
  + [指定使用客户提供的密钥的服务器端加密 (SSE-C)。](specifying-s3-c-encryption.md)

  
+ **客户端加密** – 您在客户端加密数据并将加密的数据上传到 Amazon S3。在这种情况下，您需要管理加密过程、加密密钥和相关的工具。

  要配置客户端加密，请参阅 [使用客户端加密保护数据](UsingClientSideEncryption.md)。

要查看存储字节的加密百分比，您可以使用 Amazon S3 Storage Lens 存储统计管理工具指标。S3 Storage Lens 存储统计管理工具是一项云存储分析功能，您可以使用它在整个组织范围内了解对象存储的使用情况和活动。有关更多信息，请参阅[使用 S3 Storage Lens 存储统计管理工具访问存储活动和使用情况](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage_lens?icmpid=docs_s3_user_guide_UsingEncryption.html)。有关指标的完整列表，请参阅 [S3 Storage Lens 存储统计管理工具指标词汇表](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage_lens_metrics_glossary.html?icmpid=docs_s3_user_guide_UsingEncryption)。

有关服务器端加密、客户端加密和传输中加密的更多信息，请查看下面的主题。

**Topics**
+ [使用服务器端加密保护数据](serv-side-encryption.md)
+ [使用客户端加密保护数据](UsingClientSideEncryption.md)
+ [利用加密来保护传输中数据](UsingEncryptionInTransit.md)

# 使用服务器端加密保护数据
<a name="serv-side-encryption"></a>

**重要**  
从 2026 年 4 月开始，AWS 将对所有新存储桶禁用具有客户提供密钥的服务器端加密（SSE-C）。此外，对于 AWS 账户中没有任何 SSE-C 加密数据的所有现有存储桶，都将禁用 SSE-C 加密。通过这些更改，少数需要 SSE-C 加密的应用程序必须在创建存储桶后，专门通过 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API 启用 SSE-C。在这些情况下，您可能需要更新自动化脚本、CloudFormation 模板或其他基础设施配置工具来配置这些设置。有关更多信息，请参阅 [AWS Storage 博客文章](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)。

**重要**  
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 在将您的数据写入 AWS 数据中心内的磁盘时会在对象级别加密这些数据，并在您访问这些数据时解密这些数据。只要您验证了您的请求并且拥有访问权限，您访问加密和未加密对象的方式就没有区别。例如，如果您使用预签名的 URL 来共享您的对象，那么对于加密和解密的对象，该 URL 的工作方式是相同的。此外，在您列出存储桶中的对象时，列表 API 操作会返回所有对象的列表（无论对象是否加密）。

默认情况下，所有 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/)。

**注意**  
您不能对同一个对象应用不同类型的服务器端加密。

如果您需要加密现有对象，请使用 S3 批量操作和 S3 清单。有关更多信息，请参阅[使用 Amazon S3 批量操作加密对象](https://aws.amazon.com/blogs/storage/encrypting-objects-with-amazon-s3-batch-operations/)和[使用批量操作批量执行对象操作](batch-ops.md)。

在 Amazon S3 中存储数据时，对于服务器端加密，您有四个互斥的选项，具体取决于您选择如何管理加密密钥和要应用的加密层数。

**具有 Amazon S3 托管密钥的服务器端加密（SSE-S3）**  
默认情况下，所有 Amazon S3 存储桶都配置了加密。服务器端加密的默认选项是使用 Amazon S3 托管式密钥（SSE-S3）。每个对象都使用唯一的密钥来进行加密。作为额外的保护措施，SSE-S3 使用定期轮换的根密钥加密密钥本身。SSE-S3 使用可用的最强数据块密码之一 [即 256 位高级加密标准（AES-256）] 来加密您的数据。有关更多信息，请参阅 [使用具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）](UsingServerSideEncryption.md)。

**具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS）**  
具有 AWS KMS keys 的服务器端加密（SSE-KMS）是通过将 AWS KMS 服务与 Amazon S3 集成来提供的。使用 AWS KMS，您可以更好地控制您的密钥。例如，您可以查看单独的密钥、编辑控制策略以及遵循 AWS CloudTrail 中的密钥。此外，您还可以创建和管理客户自主管理型密钥，或者使用对于您、服务和区域为唯一的 AWS 托管式密钥。有关更多信息，请参阅 [使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）](UsingKMSEncryption.md)。

**具有 AWS Key Management Service（AWS KMS）密钥的双层服务器端加密（DSSE-KMS）**  
具有 AWS KMS keys的双层服务器端加密（DSSE-KMS）与 SSE-KMS 类似，但 DSSE-KMS 应用两个独立的 AES-256 加密层而不是一层：首先使用 AWS KMS 数据加密密钥，然后使用单独的 Amazon S3 托管式加密密钥。由于这两层加密都应用于服务器端的对象，因此您可以使用各种 AWS 服务和工具来分析 S3 中的数据，同时使用可以满足多层加密的合规性要求的加密方法。有关更多信息，请参阅 [使用具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）](UsingDSSEncryption.md)。

**具有客户提供密钥的服务器端加密（SSE-C）**  
使用具有客户提供的密钥的服务器端加密（SSE-C）时，您管理加密密钥，而 Amazon S3 管理加密（在它对磁盘进行写入时）和解密（在您访问您的对象时）。有关更多信息，请参阅 [使用具有客户提供的密钥的服务器端加密（SSE-C）](ServerSideEncryptionCustomerKeys.md)。

**注意**  
当为 Amazon FSx 文件系统使用接入点时，使用 S3 接入点，您有一个服务器端加密选项。  
所有 Amazon FSx 文件系统默认情况下都配置了加密，并通过使用 AWS Key Management Service 管理的密钥进行静态加密。当向文件系统写入数据和从文件系统读取数据时，数据会在文件系统上自动加密和解密。这些过程由 Amazon FSx 透明地进行处理。

# 为 Amazon S3 存储桶设置默认服务器端加密行为
<a name="bucket-encryption"></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）来自动加密对象。此加密设置适用于 Amazon S3 存储桶中的所有对象。

如果您需要对密钥进行更多控制，例如管理密钥轮换和访问策略授予，则可以选择使用具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS），或具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）。有关编辑 KMS 密钥的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[编辑密钥](https://docs.aws.amazon.com/kms/latest/developerguide/editing-keys.html)。

**注意**  
我们已更改存储桶，以自动加密新上传的对象。如果您之前创建的存储桶没有默认加密，则 Amazon S3 在默认情况下将使用 SSE-S3 为存储桶启用加密。对于已配置 SSE-S3 或 SSE-KMS 的现有存储桶的默认加密配置，不会进行任何更改。如果您想使用 SSE-KMS 加密您的对象，则必须在存储桶设置中更改加密类型。有关更多信息，请参阅 [使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）](UsingKMSEncryption.md)。

当您将存储桶配置为使用 SSE-KMS 的默认加密时，您还可以启用 S3 存储桶密钥，以减少从 Amazon S3 到 AWS KMS 的请求流量并降低加密成本。有关更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

要识别已启用 SSE-KMS 进行默认加密的存储桶，您可以使用 Amazon S3 Storage Lens 存储统计管理工具指标。S3 Storage Lens 存储统计管理工具是一项云存储分析功能，您可以使用它在整个组织范围内了解对象存储的使用情况和活动。有关更多信息，请参阅[使用 S3 Storage Lens 存储统计管理工具保护您的数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-lens-data-protection.html?icmpid=docs_s3_user_guide_bucket-encryption.html)。

在使用服务器端加密时，Amazon S3 在将对象保存到其磁盘上之前对其进行加密，并在下载对象时对其进行解密。有关使用服务器端加密和加密密钥管理来保护数据的更多信息，请参阅[使用服务器端加密保护数据](serv-side-encryption.md)。

有关默认加密所需的权限的更多信息，请参阅《Amazon Simple Storage Service API 参考》**中的 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html)。

您可以使用 Amazon S3 控制台、AWS SDK、Amazon S3 REST API 和 AWS 命令行界面（AWS CLI）为 S3 存储桶配置 Amazon S3 默认加密行为。

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

也可以使用 `CopyObject` API 操作或 `copy-object` AWS CLI 命令加密现有对象。有关更多信息，请参阅 *AWS 存储博客*的博客文章：[使用 AWS CLI 加密现有 Amazon S3 对象](https://aws.amazon.com/blogs/storage/encrypting-existing-amazon-s3-objects-with-the-aws-cli/)。

**注意**  
将默认存储桶加密设置为 SSE-KMS 的 Amazon S3 存储桶不能用作 [使用服务器访问日志记录来记录请求](ServerLogs.md) 的目标存储桶。对于服务器访问日志目标存储桶，仅支持 SSE-S3 默认加密。

## 使用 SSE-KMS 加密进行跨账户操作
<a name="bucket-encryption-update-bucket-policy"></a>

在对跨账户操作使用加密时，请注意以下事项：
+ 如果未在请求时提供 AWS KMS key Amazon 资源名称（ARN）或别名，也未通过存储桶的默认加密配置提供它们时，则使用 AWS 托管式密钥（`aws/s3`）。
+ 如果您使用您的 KMS 密钥所在的相同 AWS 账户中的 AWS Identity and Access Management（IAM）主体上传或访问 S3 对象，则可以使用 AWS 托管式密钥（`aws/s3`）。
+ 如果您希望授予对 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/)

## 将默认加密用于复制
<a name="bucket-encryption-replication"></a>

在为复制目标存储桶启用默认加密后，将应用以下加密行为：
+ 如果未对源存储桶中的对象进行加密，则将使用目标存储桶的默认加密设置对目标存储桶中的副本对象进行加密。因此，源对象的实体标签（ETag）与副本对象的 ETag 不同。如果您有使用 ETag 的应用程序，则必须更新这些应用程序以弥补这种差异。
+ 如果使用具有 Amazon S3 托管密钥的服务器端加密（SSE-S3）、具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS）或具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）来加密源存储桶中的对象，则目标存储桶中的副本对象使用与源对象相同类型的加密。不会使用目标存储桶的默认加密设置。

有关使用 SSE-KMS 进行默认加密的更多信息，请参阅[复制加密对象](replication-config-for-kms-objects.md)。

## 将 Amazon S3 存储桶密钥用于默认加密
<a name="bucket-key-default-encryption"></a>

当将存储桶配置为使用 SSE-KMS 作为新对象的默认加密行为时，还可以配置 S3 存储桶密钥。S3 存储桶密钥可减少从 Amazon S3 到 AWS KMS 的事务数量，从而降低 SSE-KMS 的成本。

当您将存储桶配置为使用 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 存储桶密钥](bucket-key.md)。

# 配置默认加密
<a name="default-bucket-encryption"></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）来自动加密新对象。这种加密适用于您的 Amazon S3 存储桶中的所有新对象，并且不收取任何费用。

如果您需要对加密密钥进行更多控制，例如管理密钥轮换和访问策略授予，则可以选择使用具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS），或具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）。有关 SSE-KMS 的更多信息，请参阅 [使用 AWS KMS (SSE-KMS) 指定服务器端加密](specifying-kms-encryption.md)。有关 DSSE-KMS 的更多信息，请参阅[使用具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）](UsingDSSEncryption.md)。

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

当您将默认存储桶加密设置为 SSE-KMS 时，还可以配置 S3 存储桶密钥以降低 AWS KMS 请求成本。有关更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

**注意**  
如果使用 [PutBucketEncryption](https://docs.aws.amazon.com//AmazonS3/latest/API/API_PutBucketEncryption.html) 将默认存储桶加密设置为 SSE-KMS，则应验证您的 KMS 密钥 ID 是否正确。Amazon S3 不验证 PutBucketEncryption 请求中提供的 KMS 密钥 ID。

对 S3 存储桶使用默认加密不会产生额外的费用。请求配置默认加密行为会产生标准 Amazon S3 请求费用。有关定价的信息，请参阅 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)。对于 SSE-KMS 和 DSSE-KMS，将会产生 AWS KMS 费用，这些费用在 [AWS KMS 定价](https://aws.amazon.com/kms/pricing/)中列出。

默认加密不支持具有客户提供的密钥的服务器端加密（SSE-C）。

您可以使用 Amazon S3 控制台、AWS SDK、Amazon S3 REST API 和 AWS Command Line Interface（AWS CLI）为 S3 存储桶配置 Amazon S3 默认加密。

**启用默认加密之前需要注意的更改**  
在为存储桶启用默认加密后，将会应用以下加密行为：
+ 在启用默认加密之前，存储桶中已存在的对象的加密没有变化。
+ 在启用默认加密后上传对象时：
  + 如果您的 `PUT` 请求标头不包含加密信息，则 Amazon S3 将使用存储桶的默认加密设置来加密对象。
  + 如果您的 `PUT` 请求标头包含加密信息，则 Amazon S3 将使用 `PUT` 请求中的加密信息加密对象，然后再将对象存储在 Amazon S3 中。
+ 如果您将 SSE-KMS 或 DSSE-KMS 选项用于默认加密配置，则您将受到 AWS KMS 的每秒请求数（RPS）限额限制。有关 AWS KMS 限额以及如何请求增加限额的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[限额](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html)。

**注意**  
在启用默认加密之前上传的对象将不会加密。有关加密现有对象的信息，请参阅[为 Amazon S3 存储桶设置默认服务器端加密行为](bucket-encryption.md)。

## 使用 S3 控制台
<a name="bucket-encryption-how-to-set-up-console"></a>

**在 Amazon S3 存储桶上配置默认加密**

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

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

1. 在 **Buckets**（存储桶）列表中，请选择您想要的存储桶的名称。

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

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

1. 要配置加密，请在**加密类型**下，选择以下选项之一：
   + **具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）**
   + **具有 AWS Key Management Service 密钥的服务器端加密（SSE-KMS）**
   + **具有 AWS Key Management Service 密钥的双层服务器端加密（DSSE-KMS）**
**重要**  
如果您将 SSE-KMS 或 DSSE-KMS 选项用于默认加密配置，则您将受到 AWS KMS 的每秒请求数（RPS）限额限制。有关 AWS KMS 限额以及如何请求增加限额的更多信息，请参阅《AWS Key Management Service 开发人员指南》**中的[限额](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html)。

   默认情况下，存储桶和新对象使用 SSE-S3 加密，除非您为存储桶指定其他类型的默认加密。有关原定设置加密的更多信息，请参阅[为 Amazon S3 存储桶设置默认服务器端加密行为](bucket-encryption.md)。

   有关使用 Amazon S3 服务器端加密对数据进行加密的更多信息，请参阅[使用具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）](UsingServerSideEncryption.md)。

1. 如果您选择**具有 AWS Key Management Service 密钥的服务器端加密（SSE-KMS）**或**具有 AWS Key Management Service 密钥的双层服务器端加密（DSSE-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 密钥。选择**从您的 KMS 密钥中选择**时，S3 控制台每个区域仅列出 100 个 KMS 密钥。如果在同一区域中有超过 100 个 KMS，您只会在 S3 控制台中看到前 100 个 KMS 密钥。要使用控制台中未列出的 KMS 密钥，请选择**输入 AWS KMS key ARN**，然后输入 KMS 密钥 ARN。  
在 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 与 Amazon S3 结合使用的更多信息，请参阅[使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）](UsingKMSEncryption.md)。有关使用 DSSE-KMS 的更多信息，请参阅[使用具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）](UsingDSSEncryption.md)。

   1. 将存储桶配置为使用 SSE-KMS 进行默认加密时，您还可以启用 S3 存储桶密钥。S3 存储桶密钥可通过减少从 Amazon S3 到 AWS KMS 的请求流量，降低加密成本。有关更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。

      要使用 S3 存储桶密钥，请在 **Bucket Key**（存储桶密钥）下，选择 **Enable**（启用）。
**注意**  
DSSE-KMS 不支持 S3 存储桶密钥。

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

## 使用 AWS CLI
<a name="default-bucket-encryption-cli"></a>

这些示例说明如何使用 SSE-S3 或将 SSE-KMS 与 S3 存储桶密钥结合使用来配置默认加密。

有关默认加密的更多信息，请参阅[为 Amazon S3 存储桶设置默认服务器端加密行为](bucket-encryption.md)。有关使用 AWS CLI 配置默认加密的更多信息，请参阅 [put-bucket-encryption](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-encryption.html)。

**Example – 使用 SSE-S3 进行默认加密**  
此示例使用 Amazon S3 托管密钥来配置默认存储桶加密。  

```
aws s3api put-bucket-encryption --bucket amzn-s3-demo-bucket --server-side-encryption-configuration '{
    "Rules": [
        {
            "ApplyServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
            }
        }
    ]
}'
```

**Example – 使用 S3 存储桶密钥通过 SSE-KMS 进行默认加密**  
此示例使用 S3 存储桶密钥通过 SSE-KMS 配置默认存储桶加密。  

```
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
            }
        ]
    }'
```

## 使用 REST API
<a name="bucket-encryption-how-to-set-up-api"></a>

使用 REST API `PutBucketEncryption` 操作可启用默认加密，并设置要使用的服务器端加密类型：SSE-S3、SSE-KMS 或 DSSE-KMS。

有关更多信息，请参阅《Amazon Simple Storage Service API 参考》**中的 [https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTencryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTencryption.html)。

# 使用 AWS CloudTrail 和 Amazon EventBridge 监控默认加密
<a name="bucket-encryption-tracking"></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)。

您可以使用 AWS CloudTrail 事件跟踪 Amazon S3 存储桶的默认加密配置请求。CloudTrail 日志中使用以下 API 事件名称：
+ `PutBucketEncryption`
+ `GetBucketEncryption`
+ `DeleteBucketEncryption`

您还可以创建 EventBridge 规则，以匹配这些 API 调用的 CloudTrail 事件。有关 CloudTrail 事件的更多信息，请参阅[使用控制台为存储桶中的对象启用日志记录功能](enable-cloudtrail-logging-for-s3.md#enable-cloudtrail-events)。有关 EventBridge 事件的更多信息，请参阅 [AWS 服务中的事件](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-service-event.html)。

您可以使用 CloudTrail 日志执行对象级 Amazon S3 操作，以跟踪向 Amazon S3 发出的 `PUT` 和 `POST` 请求。您可以使用这些操作来验证在传入 `PUT` 请求不包含加密标头时是否使用默认加密来加密对象。

当 Amazon S3 使用默认加密设置来加密对象时，日志将包含以下字段之一作为名称/值对：`"SSEApplied":"Default_SSE_S3"`、`"SSEApplied":"Default_SSE_KMS"` 或 `"SSEApplied":"Default_DSSE_KMS"`。

当 Amazon S3 使用 `PUT` 加密标头来加密对象时，日志将包含以下字段之一作为名称/值对：`"SSEApplied":"SSE_S3"`、`"SSEApplied":"SSE_KMS"`、`"SSEApplied":"DSSE_KMS"` 或 `"SSEApplied":"SSE_C"`。

对于分段上传，该信息包含在 `InitiateMultipartUpload` API 操作请求中。有关使用 CloudTrail 和 CloudWatch 的更多信息，请参阅[Amazon S3 中的日志记录和监控](monitoring-overview.md)。

# 默认加密常见问题解答
<a name="default-encryption-faq"></a>

Amazon S3 现在将具有 Amazon S3 托管密钥的服务器端加密（SSE-S3）作为 Amazon S3 中每个存储桶的基本加密级别。从 2023 年 1 月 5 日起，上传到 Amazon S3 的所有新对象都将自动加密，不会产生额外费用，也不会影响性能。使用 256 位高级加密标准（AES-256）的 SSE-S3 会自动应用于所有新存储桶和任何尚未配置默认加密的现有 S3 存储桶。S3 存储桶默认加密配置和上传的新对象的自动加密状态可在 AWS CloudTrail 日志、S3 清单、S3 Storage Lens 存储统计管理工具、Amazon S3 控制台中获得，并可用作 AWS Command Line Interface（AWS CLI）和 AWS SDK 中的附加 Amazon S3 API 响应标头。

以下各部分回答了有关此更新的问题。

**Amazon S3 会更改已配置了默认加密的现有存储桶的默认加密设置吗？**  
不会。对于已配置 SSE-S3 或具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS）的现有存储桶的默认加密配置，不会发生任何更改。有关如何设置存储桶的默认加密行为的更多信息，请参阅[为 Amazon S3 存储桶设置默认服务器端加密行为](bucket-encryption.md)。有关 SSE-S3 和 SSE-KMS 加密设置的更多信息，请参阅[使用服务器端加密保护数据](serv-side-encryption.md)。

**是否会在未配置默认加密的现有存储桶上启用默认加密？**  
可以。Amazon S3 现在在所有现有未加密的存储桶上配置默认加密，以应用具有 Amazon S3 托管密钥的服务器端加密（SSE-S3），作为对上传到这些存储桶的新对象的基本加密级别。已在现有未加密存储桶中的对象不会自动加密。

**如何查看新对象上传的默认加密状态？**  
目前，您可以在 AWS CloudTrail 日志、S3 清单、S3 Storage Lens 存储统计管理工具、Amazon S3 控制台中查看新上传的对象的默认加密状态，并可将其作为 AWS Command Line Interface（AWS CLI）和 AWS SDK 中的附加 Amazon S3 API 响应标头。
+ 要查看您的 CloudTrail 事件，请参阅《AWS CloudTrail 用户指南》**中的[在 CloudTrail 控制台中查看 CloudTrail 事件](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events-console.html)。CloudTrail 日志为针对 Amazon S3 的 `PUT` 和 `POST` 请求提供 API 跟踪。当使用默认加密来加密存储桶中的对象时，关于 `PUT` 和 `POST` API 请求的 CloudTrail 日志将包含以下字段作为名称/值对：`"SSEApplied":"Default_SSE_S3"`。
+ 要查看 S3 清单中新对象上传的自动加密状态，请将 S3 清单报告配置为包含 **Encryption**（加密）元数据字段，然后在报告中查看每个新对象的加密状态。有关更多信息，请参阅[设置 Amazon S3 清单](https://docs.aws.amazon.com/AmazonS3/latest/userguide/configure-inventory.html#storage-inventory-setting-up)。
+ 要在 S3 Storage Lens 存储统计管理工具中查看新对象上传的自动加密状态，请配置 S3 Storage Lens 存储统计管理工具控制面板，并在控制面板的 **Data protection**（数据保护）类别中查看 **Encrypted bytes**（加密字节数）和 **Encrypted object count**（加密对象计数）指标。有关更多信息，请参阅[使用 S3 控制台](storage_lens_creating_dashboard.md#storage_lens_console_creating)和[在控制面板上查看 S3 Storage Lens 存储统计管理工具指标](storage_lens_view_metrics_dashboard.md)。
+ 要在 Amazon S3 控制台中查看存储桶级别的自动加密状态，请在 Amazon S3 控制台中查看 Amazon S3 存储桶的**默认加密**。有关更多信息，请参阅 [配置默认加密](default-bucket-encryption.md)。
+ 要在 AWS Command Line Interface（AWS CLI）和 AWS SDK 中将自动加密状态作为附加 Amazon S3 API 响应标头来查看，请在使用对象操作 API（如 [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) 和 [GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)）时检查响应标头 `x-amz-server-side-encryption`。

**我需要做什么才能利用这一更改？**  
您无需对现有应用程序进行任何更改。由于针对您的所有存储桶都启用了默认加密，因此上传到 Amazon S3 的所有新对象都会自动加密。

**我能否对正写入我的存储桶的新对象禁用加密？**  
不能。SSE-S3 是新的基本加密级别，适用于上传到您的存储桶的所有新对象。您无法再为新对象上传禁用加密。

**我的费用会受到影响吗？**  
不会。使用 SSE-S3 进行默认加密不会产生额外的成本。像往常一样，将向您收取存储、请求和其他 S3 特征的费用。有关定价信息，请参阅 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)。

**Amazon S3 会加密我现有的未加密对象吗？**  
不会。从 2023 年 1 月 5 日开始，Amazon S3 仅自动加密新上传的对象。要加密现有对象，您可以使用 S3 批量操作创建对象的加密副本。这些加密副本将保留现有的对象数据和名称，并将使用您指定的加密密钥进行加密。有关更多详细信息，请参阅 *AWS 存储博客*中的 [Encrypting objects with Amazon S3 Batch Operations](https://aws.amazon.com/blogs/storage/encrypting-objects-with-amazon-s3-batch-operations/)（使用 Amazon S3 批量操作加密对象）。

**在此版本之前，我没有为我的存储桶启用加密。我需要更改访问对象的方式吗？**  
不需要。使用 SSE-S3 进行默认加密，在将您的数据写入 Amazon S3 时会自动加密这些数据，并在您访问时解密这些数据。访问自动加密的对象的方式没有变化。

**我需要更改访问客户端加密的对象的方式吗？**  
不需要。所有在上传到 Amazon S3 之前经过加密的客户端加密对象都作为 Amazon S3 中已加密的加密文字对象到达。这些对象现在将具有额外的 SSE-S3 加密层。使用客户端加密对象的工作负载不要求对客户端服务或授权设置进行任何更改。

**注意**  
未使用 AWS 提供者的已更新版本的 HashiCorp Terraform 用户在创建没有客户定义的加密配置的新 S3 存储桶后，可能会看到意想不到的偏差。为避免这种偏差，请将您的 Terraform AWS 提供者版本更新为以下版本之一：任何 4.x 发行版、3.76.1 或 2.70.4。

# 更新现有数据的服务器端加密
<a name="update-sse-encryption"></a>

默认情况下，所有 Amazon S3 存储桶都配置了加密，并且通过具有 Amazon S3 托管密钥的服务器端加密（SSE-S3）来自动加密对象。此默认加密设置适用于 Amazon S3 存储桶中的所有新对象。

使用 `UpdateObjectEncryption` API 操作，您能够以原子方式更新通用存储桶中现有加密对象的服务器端加密类型，即从具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）更改为具有 AWS Key Management Service（AWS KMS）密钥的服务器端加密（SSE-KMS）。`UpdateObjectEncryption` API 操作使用[信封加密](https://docs.aws.amazon.com/kms/latest/developerguide/kms-cryptography.html#enveloping)，以使用新指定的服务器端加密类型来重新加密用于加密和解密对象的数据密钥。

Amazon S3 在不移动任何数据的情况下执行此加密类型更新。换句话说，当您使用 `UpdateObjectEncryption` 操作时，不会复制您的数据，S3 Glacier Flexible Retrieval 或 S3 Glacier Deep Archive 中的已归档对象不会恢复，S3 Intelligent-Tiering 存储类别中的对象也不会在层之间移动。此外，`UpdateObjectEncryption` 操作会保留所有对象元数据属性，包括存储类别、创建日期、上次修改日期、ETag 以及校验和属性。

通用存储桶支持的所有 S3 存储类别都支持 `UpdateObjectEncryption` 操作。您可以使用 `UpdateObjectEncryption` 操作来执行以下操作：
+ 将加密的对象从具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）更改为具有 AWS Key Management Service（AWS KMS）加密密钥的服务器端加密（SSE-KMS）。
+ 更新对象级 SSE-KMS 加密对象以使用 S3 存储桶密钥，这会减少从 Amazon S3 到 AWS KMS 的 AWS KMS 请求流量。有关更多信息，请参阅 [使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。
+ 更改用于加密数据的客户自主管理型 KMS 密钥，这样您就可以遵守自定义密钥轮换标准。

**注意**  
此操作不支持未加密的对象，也不支持使用具有 AWS KMS keys的双层服务器端加密（DSSE-KMS）或客户提供的加密密钥（SSE-C）进行加密的对象。

无论对象的大小或存储类别（包括 S3 Glacier Flexible Retrieval 或 S3 Glacier Deep Archive）如何，`UpdateObjectEncryption` 操作通常都会在数毫秒内完成。此操作不算作对 S3 Intelligent-Tiering 的访问，因此，如果您更改对象的服务器端加密类型，不频繁访问层或归档即时访问层中的对象将不会自动分层回到频繁访问层。

`UpdateObjectEncryption` 是一种对象级（数据面板）API 操作，已记录到 Amazon S3 服务器访问日志和 AWS CloudTrail 数据事件中。有关更多信息，请参阅 [Amazon S3 的日志记录选项](logging-with-S3.md)。

 `UpdateObjectEncryption` 操作的定价与 `PUT`、`COPY`、`POST` 和 `LIST` 请求相同（每 1000 个请求），并且无论底层对象的存储类别如何，均始终按照 S3 Standard 存储类别请求收费。有关更多信息，请参阅 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)。

## 限制和注意事项
<a name="update-sse-encryption-restrictions"></a>

当您使用 `UpdateObjectEncryption` 操作时，以下限制和注意事项适用：
+ `UpdateObjectEncryption` 操作不支持未加密的对象，也不支持使用具有 AWS KMS keys 的双层服务器端加密（DSSE-KMS）或客户提供的加密密钥（SSE-C）进行加密的对象。此外，您不能指定 SSE-S3 作为所请求的新加密类型 `UpdateObjectEncryption` 请求。
+ 您可以使用 `UpdateObjectEncryption` 操作来更新存储桶中启用了 S3 版本控制的对象。要更新特定版本的加密类型，您必须在 `UpdateObjectEncryption` 请求中指定版本 ID。如果未指定版本 ID，则 `UpdateObjectEncryption` 请求作用于对象的当前版本。有关 S3 版本控制的更多信息，请参阅[使用 S3 版本控制保留对象的多个版本](Versioning.md)。
+ `UpdateObjectEncryption` 操作对任何应用了 S3 对象锁定保留模式或法定保留的对象都将失败。如果某个对象具有治理模式保留期或法定保留，则在发出 `UpdateObjectEncryption` 请求之前，必须先移除该对象的对象锁定状态。您不能对应用了对象锁定合规模式保留期的对象使用 `UpdateObjectEncryption` 操作。有关 S3 对象锁定的更多信息，请参阅 [使用对象锁定以锁定对象](object-lock.md)。
+ 启用了实时复制功能的源存储桶上的 `UpdateObjectEncryption` 请求不会在目标存储桶中启动副本事件。如果要更改源存储桶和目标存储桶中对象的加密类型，则必须对源存储桶和目标存储桶中的对象发起单独的 `UpdateObjectEncryption` 请求。
+ 默认情况下，所有指定客户自主管理型 KMS 密钥的 `UpdateObjectEncryption` 请求都仅限于存储桶所有者的 AWS 账户拥有的 KMS 密钥。如果您正在使用 AWS Organizations，则可以通过联系 AWS 支持 来请求使用组织内其它成员账户拥有的 AWS KMS keys的能力。
+ 如果您使用 S3 批量复制来跨区域复制数据集，并且您的对象之前已将其服务器端加密类型从 SSE-S3 更新为 SSE-KMS，则您可能需要额外的权限。在源区域存储桶上，您必须拥有 `kms:decrypt` 权限。然后，您将需要针对目标区域中存储桶的 `kms:decrypt` 和 `kms:encrypt` 权限。
+ 您必须在您的 `UpdateObjectEncryption` 请求中提供完整的 KMS 密钥 ARN。您不能使用别名名称或别名 ARN。您可以在 AWS KMS 控制台中或使用 AWS KMS `DescribeKey` API 确定完整的 KMS 密钥 ARN。

## 所需的权限
<a name="update-sse-encryption-permissions"></a>

要执行 `UpdateObjectEncryption` 操作，您必须拥有以下权限：
+ `s3:PutObject`
+ `s3:UpdateObjectEncryption`
+ `kms:Encrypt`
+ `kms:Decrypt`
+ `kms:GenerateDataKey`
+ `kms:ReEncrypt*`

如果您正在使用 AWS Organizations，则要将此操作与组织内其它 AWS 账户提供的客户管理型 KMS 密钥结合使用，您必须具有 `organizations:DescribeAccount` 权限。还可以通过联系 AWS 支持 来请求使用组织内其它成员账户拥有的 AWS KMS keys的能力。

要执行 `UpdateObjectEncryption` 操作，请将以下 AWS Identity and Access Management（IAM）策略添加到您的 IAM 角色。要使用此策略，请将 `amzn-s3-demo-bucket` 替换为通用存储桶的名称，并将另一个 `user input placeholders` 替换为您自己的信息。

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [{
            "Sid": "AllowUpdateObjectEncryption",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:UpdateObjectEncryption",
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:GenerateDataKey",
                "kms:ReEncrypt*",
                "organizations:DescribeAccount"
            ],
            "Resource": [
                "arn:aws:s3:::amzn-s3-demo-bucket",
                "arn:aws:s3:::amzn-s3-demo-bucket/*",
                "arn:aws:kms:us-east-1:111122223333:key/01234567-89ab-cdef-0123-456789abcdef"
            ]
        }
    ]
}
```

## 批量更新加密
<a name="update-sse-encryption-bulk"></a>

要使用单个请求更新多个 Amazon S3 对象的服务器端加密类型，您可以使用 S3 批量操作。您可以为 S3 批量操作提供要操作的对象列表，也可以指示批量操作生成基于对象列表的对象元数据，包括前缀、存储类别、创建日期、加密类型、KMS 密钥 ARN 或 S3 存储桶密钥状态。S3 批量操作调用相应的 API 操作来执行指定的操作。单个批量操作作业可对包含 PB 级数据的存储桶中的数十亿个对象执行指定的操作。有关批处理操作的更多信息，请参阅[使用批量操作批量执行对象操作](batch-ops.md)。

S3 批量操作特征包括跟踪进度、发送通知并存储所有操作的详细完成报告，从而提供完全托管、可审核的无服务器体验。可以通过 Amazon S3 控制台、AWS Command Line Interface（AWS CLI）、AWS SDK 或 Amazon S3 REST API 使用 S3 批量操作。有关更多信息，请参阅 [更新对象加密](batch-ops-update-encryption.md)。

## 更新对象的加密
<a name="update-sse-encryption-single-object"></a>

您可以通过 AWS Command Line Interface（AWS CLI）、AWS SDK 或 Amazon S3 REST API 更新对象的服务器端加密类型。

### 更新对象的加密
<a name="update-sse-encryption-single-object-procedure"></a>

#### 使用 AWS CLI
<a name="update-sse-encryption-single-object-cli"></a>

要运行以下命令，您必须安装并配置 AWS CLI。如果未安装 AWS CLI，请参阅《AWS Command Line Interface 用户指南》**中的[安装或更新最新版本的 AWS CLI](https://docs.aws.amazon.com//cli/latest/userguide/getting-started-install.html)。

或者，可以从控制台中使用 AWS CloudShell 运行 AWS CLI 命令。AWS CloudShell 是一个基于浏览器、预先经过身份验证的 Shell，您可以直接从 AWS 管理控制台中启动它。有关更多信息，请参阅《AWS CloudShell 用户指南》**中的 [What is CloudShell?](https://docs.aws.amazon.com//cloudshell/latest/userguide/welcome.html) 和 [Getting started with AWS CloudShell](https://docs.aws.amazon.com//cloudshell/latest/userguide/getting-started.html)。

**使用 AWS CLI 更新对象的加密**

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

1. 使用以下命令更新通用存储桶（例如 `amzn-s3-demo-bucket`）中单个对象 (`index.html`) 的加密，以便将 SSE-KMS 与 S3 存储桶密钥结合使用：

   ```
   aws s3api update-object-encryption \
   --bucket amzn-s3-demo-bucket \
   --key index.html \
   --object-encryption '{"SSEKMS": { "KMSKeyArn": "arn:aws:kms:us-east-1:111122223333:key/f12a345a-678e-9bbb-1025-62e317037583", "BucketKeyEnabled": true }}'
   ```
**注意**  
您必须指定完整的 AWS KMS key Amazon 资源名称（ARN）。不支持 KMS 密钥 ID 和 KMS 密钥别名。

1. 运行 `head-object` 命令以查看对象的更新加密类型：

   ```
   aws s3api head-object --bucket amzn-s3-demo-bucket --key index.html
   ```

#### 使用 REST API
<a name="update-sse-encryption-single-object-rest-api"></a>

您可以发送 REST 请求以更新对象的加密。有关更多信息，请参阅 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_UpdateObjectEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UpdateObjectEncryption.html)。

#### 使用 AWS SDK
<a name="update-sse-encryption-single-object-sdk"></a>

您可以使用 AWS SDK 来更新对象的加密。有关更多信息，请参阅[支持的 SDK 的列表](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UpdateObjectEncryption.html#API_UpdateObjectEncryption_SeeAlso)。

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

**Example**  
以下 AWS SDK for Java 2.x 示例将通用存储桶中对象的加密类型更新为 SSE-KMS。  

```
    public void updateObjectEncryption(String bucketName,
                                       String objectKey,
                                       String versionId,
                                       String kmsKeyArn,
                                       boolean bucketKeyEnabled) {
        // Create the target object encryption type.
        ObjectEncryption objectEncryption = ObjectEncryption.builder()
                .ssekms(SSEKMSEncryption.builder()
                        .kmsKeyArn(kmsKeyArn)
                        .bucketKeyEnabled(bucketKeyEnabled)
                        .build())
                .build();

        // Create the UpdateObjectEncryption request.
        UpdateObjectEncryptionRequest request = UpdateObjectEncryptionRequest.builder()
                .bucket(bucketName)
                .key(objectKey)
                .versionId(versionId)
                .objectEncryption(objectEncryption)
                .build();

        // Update the object encryption.
        try {
            getS3Client().updateObjectEncryption(request);
            logger.info("Object encryption updated to SSE-KMS for {} in bucket {}", objectKey, bucketName);
        } catch (S3Exception e) {
            logger.error("Failed to update to object encryption: {} - Error code: {}", e.awsErrorDetails().errorMessage(),
                    e.awsErrorDetails().errorCode());
            throw e;
        }
    }
```

------
#### [ Python ]

**Example**  
以下 适用于 Python (Boto3) 的 AWS SDK 示例说明如何将通用存储桶中对象的加密类型更新为 SSE-KMS。  

```
response = client.update_object_encryption(
    Bucket='string',
    Key='string',
    VersionId='string',
    ObjectEncryption={
        'SSEKMS': {
                'KMSKeyArn': 'string',
                'BucketKeyEnabled': True|False
        }
    }
)
```

------

# 使用具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）
<a name="UsingServerSideEncryption"></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）进行加密。

服务器端加密可保护静态数据。Amazon S3 使用唯一的密钥来加密每个对象。作为额外的保护，它将使用定期轮换的密钥加密密钥本身。Amazon S3 服务器端加密使用 256 位高级加密标准 Galois/Counter 模式（AES-GCM）对所有上传的对象进行加密。

使用具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）不会产生额外费用。然而，请求配置默认加密特征会产生标准 Amazon S3 请求费用。有关定价的信息，请参阅 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)。

如果您要求仅使用 Amazon S3 托管密钥对上传的数据进行加密，则可以使用以下存储桶策略。例如，以下存储桶策略拒绝上传对象的权限，除非请求包含用于请求服务器端加密的 `x-amz-server-side-encryption` 标头：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "PutObjectPolicy",
  "Statement": [
    {
      "Sid": "DenyObjectsThatAreNotSSES3",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "AES256"
        }
      }
    }
   ]
}
```

------

**注意**  
服务器端加密仅加密对象数据而非加密对象元数据。

## 服务器端加密的 API 支持
<a name="APISupportforServer-SideEncryption"></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/)。

要使用对象创建 REST API 配置服务器端加密，必须提供 `x-amz-server-side-encryption` 请求标头。有关 REST API 的信息，请参阅 [使用 REST API](specifying-s3-encryption.md#SSEUsingRESTAPI)。

以下 Amazon S3 API 支持此标头：
+ **PUT 操作** - 在使用 `PUT` API 上传数据时指定请求标头。有关更多信息，请参阅 [PUT Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)。
+ **启动分段上传** - 当使用分段上传 API 操作上传大型对象时，在启动请求中指定标头。有关更多信息，请参阅[启动分段上传](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)。
+ **COPY 操作** - 在复制对象时，您同时具有源对象和目标对象。有关更多信息，请参阅 [PUT Object - 复制](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)。

**注意**  
当使用 `POST` 操作上传对象时，请在表单字段中提供相同的信息，而不是提供请求标头。有关更多信息，请参阅 [POST 对象](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)。

AWS SDK 还提供了一个可用于请求服务器端加密的包装程序 API。您还可以使用 AWS 管理控制台 来上传对象并请求服务器端加密。

有关更多常规信息，请参阅《AWS Key Management Service 开发人员指南》**中的 [AWS KMS 概念](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html)。

**Topics**
+ [服务器端加密的 API 支持](#APISupportforServer-SideEncryption)
+ [指定具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）](specifying-s3-encryption.md)

# 指定具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）
<a name="specifying-s3-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/)。

您可以使用 S3 控制台、REST API、AWS SDK 和 AWS Command Line Interface（AWS CLI）指定 SSE-S3。有关更多信息，请参阅 [为 Amazon S3 存储桶设置默认服务器端加密行为](bucket-encryption.md)。

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

本主题介绍如何使用 AWS 管理控制台设置或更改对象的加密类型。使用控制台复制对象时，Amazon S3 将按原样复制对象。这意味着，如果对源对象加密，则也会对目标对象加密。可以使用控制台添加或更改对象的加密。

**注意**  
如果对象小于 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. 在**加密设置**下，选择**使用默认加密的存储桶设置**或**覆盖默认加密的存储桶设置**。

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

   1. 在**加密类型**下，选择**具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）**。SSE-S3 使用最强的数据块密码之一 [即 256 位高级加密标准（AES-256）] 来加密每个对象。有关更多信息，请参阅 [使用具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）](UsingServerSideEncryption.md)。

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

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

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

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

创建对象时（即，上传新对象或复制现有对象时），您可以通过向请求添加 `x-amz-server-side-encryption` 标头来指定您是否希望 Amazon S3 使用 Amazon S3 托管式密钥（SSE-S3）加密您的数据。将标头的值设置为 Amazon S3 支持的加密算法 `AES256`。Amazon S3 通过返回响应标头 `x-amz-server-side-encryption` 来确认已使用 SSE-S3 存储对象。

以下 REST 上传 API 操作接受 `x-amz-server-side-encryption` 请求标头。
+ [PUT Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)
+ [PUT Object – 复制](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)
+ [POST 对象](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [开始分段上传](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)

使用分段上传 API 操作上传大型对象时，您可以通过为启动分段上传请求添加 `x-amz-server-side-encryption` 标头来指定服务器端加密。复制现有对象时，不论源对象是否已经加密，都不会加密目标对象，除非您显式请求服务器端加密。

使用 SSE-S3 加密存储对象后，以下 REST API 操作的响应标头将返回 `x-amz-server-side-encryption` 标头。
+ [PUT Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)
+ [PUT Object – 复制](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)
+ [POST 对象](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [开始分段上传](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)
+ [上传分段](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html)
+ [上传分段 – 复制](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html)
+ [完成分段上传](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html)
+ [GET Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html)
+ [HEAD Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html)

**注意**  
如果您的对象使用 SSE-S3，请不要发送 `GET` 请求和 `HEAD` 请求的加密请求标头，否则会收到 HTTP 状态代码 400（错误请求）错误。

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

使用 AWS SDK 时，您可以请求 Amazon S3 使用具有 Amazon S3 托管式加密密钥的服务器端加密（SSE-S3）。这部分提供了以多种语言使用 AWS SDK 的示例。有关其他 SDK 的信息，请转到[示例代码和库](https://aws.amazon.com/code)。

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

当您使用 适用于 Java 的 AWS SDK 上传对象时，可以使用 SSE-S3 为对象加密。要请求服务器端加密，请使用 `ObjectMetadata` 的 `PutObjectRequest` 属性设置 `x-amz-server-side-encryption` 请求标头。当您调用 `putObject()` 的 `AmazonS3Client` 方法时，Amazon S3 将加密并保存数据。

当使用分段上传 API 操作上传对象时，还可以请求 SSE-S3 加密：
+ 使用高级别分段上传 API 操作时，请在上传对象时使用 `TransferManager` 方法将服务器端加密应用于对象。可以使用将 `ObjectMetadata` 视为参数的任一上传方法。有关更多信息，请参阅 [使用分段上传操作上传对象](mpu-upload-object.md)。
+ 当使用低级别分段上传 API 操作时，应在启动分段上传时指定服务器端加密。您通过调用 `ObjectMetadata` 方法添加 `InitiateMultipartUploadRequest.setObjectMetadata()` 属性。有关更多信息，请参阅 [使用 AWS SDK（低级别 API）](mpu-upload-object.md#mpu-upload-low-level)。

不能直接更改对象的加密状态 (加密未加密的对象或解密已加密的对象)。要更改对象的加密状态，请为对象创建一个副本，从而为副本指定所需的加密状态，然后删除原始对象。仅当您显式请求服务器端加密时，Amazon S3 才会加密复制的对象。要通过 Java API 请求加密复制的对象，请使用 `ObjectMetadata` 属性在 `CopyObjectRequest` 中指定服务器端加密。

**Example 示例**  
以下示例演示如何使用 适用于 Java 的 AWS SDK 设置服务器端加密。它展示了如何执行以下任务：  
+ 使用 SSE-S3 上传新对象。
+ 通过为对象创建副本来更改对象的加密状态 (本示例中为加密之前未加密的对象)。
+ 检查对象的加密状态。
有关服务器端加密的更多信息，请参阅[使用 REST API](#SSEUsingRESTAPI)。有关创建和测试有效示例的说明，请参阅《适用于 Java 的 AWS SDK 开发人员指南》中的[入门](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/getting-started.html)。  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.internal.SSEResultBase;
import com.amazonaws.services.s3.model.*;

import java.io.ByteArrayInputStream;

public class SpecifyServerSideEncryption {

    public static void main(String[] args) {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String keyNameToEncrypt = "*** Key name for an object to upload and encrypt ***";
        String keyNameToCopyAndEncrypt = "*** Key name for an unencrypted object to be encrypted by copying ***";
        String copiedObjectKeyName = "*** Key name for the encrypted copy of the unencrypted object ***";

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();

            // Upload an object and encrypt it with SSE.
            uploadObjectWithSSEEncryption(s3Client, bucketName, keyNameToEncrypt);

            // Upload a new unencrypted object, then change its encryption state
            // to encrypted by making a copy.
            changeSSEEncryptionStatusByCopying(s3Client,
                    bucketName,
                    keyNameToCopyAndEncrypt,
                    copiedObjectKeyName);
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }

    private static void uploadObjectWithSSEEncryption(AmazonS3 s3Client, String bucketName, String keyName) {
        String objectContent = "Test object encrypted with SSE";
        byte[] objectBytes = objectContent.getBytes();

        // Specify server-side encryption.
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(objectBytes.length);
        objectMetadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
        PutObjectRequest putRequest = new PutObjectRequest(bucketName,
                keyName,
                new ByteArrayInputStream(objectBytes),
                objectMetadata);

        // Upload the object and check its encryption status.
        PutObjectResult putResult = s3Client.putObject(putRequest);
        System.out.println("Object \"" + keyName + "\" uploaded with SSE.");
        printEncryptionStatus(putResult);
    }

    private static void changeSSEEncryptionStatusByCopying(AmazonS3 s3Client,
            String bucketName,
            String sourceKey,
            String destKey) {
        // Upload a new, unencrypted object.
        PutObjectResult putResult = s3Client.putObject(bucketName, sourceKey, "Object example to encrypt by copying");
        System.out.println("Unencrypted object \"" + sourceKey + "\" uploaded.");
        printEncryptionStatus(putResult);

        // Make a copy of the object and use server-side encryption when storing the
        // copy.
        CopyObjectRequest request = new CopyObjectRequest(bucketName,
                sourceKey,
                bucketName,
                destKey);
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
        request.setNewObjectMetadata(objectMetadata);

        // Perform the copy operation and display the copy's encryption status.
        CopyObjectResult response = s3Client.copyObject(request);
        System.out.println("Object \"" + destKey + "\" uploaded with SSE.");
        printEncryptionStatus(response);

        // Delete the original, unencrypted object, leaving only the encrypted copy in
        // Amazon S3.
        s3Client.deleteObject(bucketName, sourceKey);
        System.out.println("Unencrypted object \"" + sourceKey + "\" deleted.");
    }

    private static void printEncryptionStatus(SSEResultBase response) {
        String encryptionStatus = response.getSSEAlgorithm();
        if (encryptionStatus == null) {
            encryptionStatus = "Not encrypted with SSE";
        }
        System.out.println("Object encryption status is: " + encryptionStatus);
    }
}
```

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

在上传对象时，可指示 Amazon S3 加密对象。要更改现有对象的加密状态，请复制该对象并删除源对象。默认情况下，仅当您显式请求目标对象的服务器端加密时，复制操作才会加密目标。要在 `CopyObjectRequest` 中指定 SSE-S3，请添加以下内容：

```
 ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256
```

有关如何复制对象的有效示例，请参阅 [使用 AWS SDK](copy-object.md#CopyingObjectsUsingSDKs)。

以下示例将上传对象。在请求中，该示例指示 Amazon S3 加密对象。该示例随后检索对象元数据并验证使用的加密方法。有关设置和运行代码示例的信息，请参阅《适用于 .NET 的 AWS SDK 开发人员指南》**中的[适用于 .NET 的 AWS SDK 入门](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class SpecifyServerSideEncryptionTest
    {
        private const string bucketName = "*** bucket name ***";
        private const string keyName = "*** key name for object created ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;

        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            WritingAnObjectAsync().Wait();
        }

        static async Task WritingAnObjectAsync()
        {
            try
            {
                var putRequest = new PutObjectRequest
                {
                    BucketName = bucketName,
                    Key = keyName,
                    ContentBody = "sample text",
                    ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256
                };

                var putResponse = await client.PutObjectAsync(putRequest);

                // Determine the encryption state of an object.
                GetObjectMetadataRequest metadataRequest = new GetObjectMetadataRequest
                {
                    BucketName = bucketName,
                    Key = keyName
                };
                GetObjectMetadataResponse response = await client.GetObjectMetadataAsync(metadataRequest);
                ServerSideEncryptionMethod objectEncryption = response.ServerSideEncryptionMethod;

                Console.WriteLine("Encryption method used: {0}", objectEncryption.ToString());
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        }
    }
}
```

------
#### [ PHP ]

本主题介绍如何使用 适用于 PHP 的 AWS SDK 版本 3 中的类来将 SSE-S3 添加到您上传到 Amazon S3 的对象。有关适用于 Ruby 的 AWS 开发工具包 API 的更多信息，请转到[适用于 Ruby 的 AWS 开发工具包 – 版本 2](https://docs.aws.amazon.com/sdkforruby/api/index.html)。

要将对象上传到 Amazon S3，请使用 [Aws\$1S3\$1S3Client::putObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject) 方法。要将 `x-amz-server-side-encryption` 请求标头添加到您的上传请求，请使用值 `ServerSideEncryption` 指定 `AES256` 参数，如以下代码示例中所示。有关服务器端加密请求的信息，请参阅 [使用 REST API](#SSEUsingRESTAPI)。

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';

// $filepath should be an absolute path to a file on disk.
$filepath = '*** Your File Path ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Upload a file with server-side encryption.
$result = $s3->putObject([
    'Bucket'               => $bucket,
    'Key'                  => $keyname,
    'SourceFile'           => $filepath,
    'ServerSideEncryption' => 'AES256',
]);
```

作为响应，Amazon S3 会返回 `x-amz-server-side-encryption` 标头以及已用于加密对象数据的加密算法的值。

在使用分段上传 API 操作上传大型对象时，您可以为正在上传的对象指定 SSE-S3，如下所示：
+ 如果您使用低级别分段上传 API 操作，请在调用 [ Aws\$1S3\$1S3Client::createMultipartUpload()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload) 方法时指定服务器端加密。要向请求添加 `x-amz-server-side-encryption` 请求标头，请使用值 `array` 指定 `ServerSideEncryption` 参数的 `AES256` 密钥。有关低级别分段上传 API 操作的更多信息，请参阅[使用 AWS SDK（低级别 API）](mpu-upload-object.md#mpu-upload-low-level)。
+ 当使用高级别分段上传 API 操作时，请使用 [CreateMultipartUpload](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload) API 操作的 `ServerSideEncryption` 参数来指定服务器端加密。有关将 `setOption()` 方法与高级别分段上传 API 操作结合使用的示例，请参阅[使用分段上传操作上传对象](mpu-upload-object.md)。

要确定现有对象的加密状态，请通过调用 [Aws\$1S3\$1S3Client::headObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#headobject) 方法检索对象元数据，如下面的 PHP 代码示例所示。

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Check which server-side encryption algorithm is used.
$result = $s3->headObject([
    'Bucket' => $bucket,
    'Key'    => $keyname,
]);
echo $result['ServerSideEncryption'];
```

要更改现有对象的加密状态，请使用 [Aws\$1S3\$1S3Client::copyObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#copyobject) 方法复制对象并删除源对象。默认情况下，`copyObject()` 不会加密目标，除非您通过将值 `AES256` 用于 `ServerSideEncryption` 参数，显式请求对目标对象进行服务器端加密。以下 PHP 代码示例将复制对象并向复制的对象添加服务器端加密。

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$sourceBucket = '*** Your Source Bucket Name ***';
$sourceKeyname = '*** Your Source Object Key ***';

$targetBucket = '*** Your Target Bucket Name ***';
$targetKeyname = '*** Your Target Object Key ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Copy an object and add server-side encryption.
$s3->copyObject([
    'Bucket'               => $targetBucket,
    'Key'                  => $targetKeyname,
    'CopySource'           => "$sourceBucket/$sourceKeyname",
    'ServerSideEncryption' => 'AES256',
]);
```

有关更多信息，请参阅以下主题：
+ [适用于 PHP 的 AWS SDK面向 Amazon S3 Aws\$1S3\$1S3Client 类的](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html) 
+ [适用于 PHP 的 AWS SDK 文档](https://aws.amazon.com/documentation/sdk-for-php/)

------
#### [ Ruby ]

在使用 适用于 Ruby 的 AWS SDK 上传对象时，您可以指定使用 SSE-S3 对存储的对象进行静态加密。在您读回对象时，它将自动解密。

下面的 适用于 Ruby 的 AWS SDK 版本 3 示例演示了如何指定对上传到 Amazon S3 的文件进行静态加密。

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectPutSseWrapper
  attr_reader :object

  # @param object [Aws::S3::Object] An existing Amazon S3 object.
  def initialize(object)
    @object = object
  end

  def put_object_encrypted(object_content, encryption)
    @object.put(body: object_content, server_side_encryption: encryption)
    true
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't put your content to #{object.key}. Here's why: #{e.message}"
    false
  end
end

# Example usage:
def run_demo
  bucket_name = "amzn-s3-demo-bucket"
  object_key = "my-encrypted-content"
  object_content = "This is my super-secret content."
  encryption = "AES256"

  wrapper = ObjectPutSseWrapper.new(Aws::S3::Object.new(bucket_name, object_content))
  return unless wrapper.put_object_encrypted(object_content, encryption)

  puts "Put your content into #{bucket_name}:#{object_key} and encrypted it with #{encryption}."
end

run_demo if $PROGRAM_NAME == __FILE__
```

下面的代码示例演示了如何确定现有对象的加密状态。

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectGetEncryptionWrapper
  attr_reader :object

  # @param object [Aws::S3::Object] An existing Amazon S3 object.
  def initialize(object)
    @object = object
  end

  # Gets the object into memory.
  #
  # @return [Aws::S3::Types::GetObjectOutput, nil] The retrieved object data if successful; otherwise nil.
  def object
    @object.get
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't get object #{@object.key}. Here's why: #{e.message}"
  end
end

# Example usage:
def run_demo
  bucket_name = "amzn-s3-demo-bucket"
  object_key = "my-object.txt"

  wrapper = ObjectGetEncryptionWrapper.new(Aws::S3::Object.new(bucket_name, object_key))
  obj_data = wrapper.get_object
  return unless obj_data

  encryption = obj_data.server_side_encryption.nil? ? 'no' : obj_data.server_side_encryption
  puts "Object #{object_key} uses #{encryption} encryption."
end

run_demo if $PROGRAM_NAME == __FILE__
```

如果存储在 Amazon S3 中的对象没有使用服务器端加密，则该方法将返回 `null`。

要更改现有对象的加密状态，请复制该对象并删除源对象。默认情况下，复制方法不会加密目标，除非您明确请求服务器端加密。您可以通过在选项的哈希参数中指定 `server_side_encryption` 值来请求对目标对象进行加密，如下面的 Ruby 代码示例所示。此代码示例演示如何复制对象和使用 SSE-S3 加密副本。

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectCopyEncryptWrapper
  attr_reader :source_object

  # @param source_object [Aws::S3::Object] An existing Amazon S3 object. This is used as the source object for
  #                                        copy actions.
  def initialize(source_object)
    @source_object = source_object
  end

  # Copy the source object to the specified target bucket, rename it with the target key, and encrypt it.
  #
  # @param target_bucket [Aws::S3::Bucket] An existing Amazon S3 bucket where the object is copied.
  # @param target_object_key [String] The key to give the copy of the object.
  # @return [Aws::S3::Object, nil] The copied object when successful; otherwise, nil.
  def copy_object(target_bucket, target_object_key, encryption)
    @source_object.copy_to(bucket: target_bucket.name, key: target_object_key, server_side_encryption: encryption)
    target_bucket.object(target_object_key)
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't copy #{@source_object.key} to #{target_object_key}. Here's why: #{e.message}"
  end
end

# Example usage:
def run_demo
  source_bucket_name = "amzn-s3-demo-bucket1"
  source_key = "my-source-file.txt"
  target_bucket_name = "amzn-s3-demo-bucket2"
  target_key = "my-target-file.txt"
  target_encryption = "AES256"

  source_bucket = Aws::S3::Bucket.new(source_bucket_name)
  wrapper = ObjectCopyEncryptWrapper.new(source_bucket.object(source_key))
  target_bucket = Aws::S3::Bucket.new(target_bucket_name)
  target_object = wrapper.copy_object(target_bucket, target_key, target_encryption)
  return unless target_object

  puts "Copied #{source_key} from #{source_bucket_name} to #{target_object.bucket_name}:#{target_object.key} and "\
       "encrypted the target with #{target_object.server_side_encryption} encryption."
end

run_demo if $PROGRAM_NAME == __FILE__
```

------

## 使用 AWS CLI
<a name="sse-s3-aws-cli"></a>

要在使用 AWS CLI 上传对象时指定 SSE-S3，请使用以下示例。

```
aws s3api put-object --bucket amzn-s3-demo-bucket1 --key object-key-name --server-side-encryption AES256  --body file path
```

有关更多信息，请参阅 *AWS CLI 参考*中的 [put-object](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html)。要在使用 AWS CLI 复制对象时指定 SSE-S3，请参阅 [copy-object](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html)。

## 使用 CloudFormation
<a name="ss3-s3-cfn"></a>

有关使用 CloudFormation 设置加密的示例，请参阅《AWS CloudFormation 用户指南》**的 `AWS::S3::Bucket ServerSideEncryptionRule` 主题中的[使用默认加密创建存储桶](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionrule.html#aws-properties-s3-bucket-serversideencryptionrule--examples--Create_a_bucket_with_default_encryption)和[通过 AWS KMS 服务器端加密使用 S3 存储桶密钥创建存储桶](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionrule.html#aws-properties-s3-bucket-serversideencryptionrule--examples--Create_a_bucket_using_AWS_KMS_server-side_encryption_with_an_S3_Bucket_Key)示例。

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

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

在将对象上传到 Amazon S3 时，使用具有 AWS Key Management Service（AWS KMS）密钥的双层服务器端加密（DSSE-KMS）将会对于对象应用两层加密。DSSE-KMS 可帮助您更轻松地满足合规性标准，这些标准要求您对数据应用多层加密并完全控制您的加密密钥。

DSSE-KMS 中的“双”是指应用于数据的两个独立的 AES-256 加密层：
+ *第一层：*数据使用由 AWS KMS 生成的唯一数据加密密钥（DEK）进行加密
+ *第二层：*已加密的数据使用由 Amazon S3 管理的单独 AES-256 加密密钥再次加密

这与标准 SSE-KMS 不同，后者仅应用单层加密。双层方法可确保即使一个加密层遭到破坏，您的数据仍受到第二层保护，从而增强了安全性。这种额外的安全性伴随着处理开销和 AWS KMS API 调用的增加，与标准 SSE-KMS 相比，这会导致成本更高。有关 DSSE-KMS 定价的更多信息，请参阅《AWS Key Management Service Developer Guide》中的 [AWS KMS key concepts](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms_keys) 以及 [AWS KMS 定价](https://aws.amazon.com/kms/pricing)。

将 DSSE-KMS 加密用于 Amazon S3 存储桶时，AWS KMS 密钥必须位于该存储桶所在的同一区域中。此外，当为对象请求 DSSE-KMS 时，作为对象元数据一部分的 S3 校验和将以加密形式存储。有关校验和的更多信息，请参阅[在 Amazon S3 中检查对象完整性](checking-object-integrity.md)。

**注意**  
DSSE-KMS 不支持 S3 存储桶密钥。

DSSE-KMS 和标准 SSE-KMS 之间的主要区别在于：
+ **加密层：**DSSE-KMS 应用两个独立的 AES-256 加密层，而标准 SSE-KMS 应用一层
+ **安全性：**DSSE-KMS 提供针对潜在加密漏洞的增强保护
+ **合规性：**DSSE-KMS 有助于满足强制要求多层加密的监管要求
+ **性能：**由于额外的加密处理，DSSE-KMS 的延迟稍高
+ **成本：**由于计算开销增加和额外的 AWS KMS 操作，DSSE-KMS 会产生更高的费用

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

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

****  

```
{
             "Version":"2012-10-17",		 	 	 
             "Id": "PutObjectPolicy",
             "Statement": [{
                   "Sid": "DenyUnEncryptedObjectUploads",
                   "Effect": "Deny",
                   "Principal": {
                       "AWS": "arn:aws:iam::111122223333:root"
                   },
                   "Action": "s3:PutObject",
                   "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
                   "Condition": {
                      "StringNotEquals": {
                         "s3:x-amz-server-side-encryption": "aws:kms:dsse"
                      }
                   }
                }
             ]
          }
```

------

**Topics**
+ [指定具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）](specifying-dsse-encryption.md)

# 指定具有 AWS KMS 密钥的双层服务器端加密（DSSE-KMS）
<a name="specifying-dsse-encryption"></a>

当您上传新对象或复制现有对象时，您可以应用加密。

您可以使用 Amazon S3 控制台、Amazon S3 REST API 和 AWS Command Line Interface（AWS CLI）指定 DSSE-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-dsse"></a>

本节介绍如何使用 Amazon S3 控制台，将对象的加密类型设置或更改为使用具有 AWS Key Management Service（AWS KMS）密钥的双层服务器端加密（DSSE-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. 在**加密设置**下，选择**使用默认加密的存储桶设置**或**覆盖默认加密的存储桶设置**。

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

   1. 在**加密类型**下，选择**具有 AWS Key Management Service 密钥的双层服务器端加密（DSSE-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. 对于**存储桶密钥**，选择**禁用**。DSSE-KMS 不支持 S3 存储桶密钥。

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

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

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

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

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

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

**Topics**
+ [支持 DSSE-KMS 的 Amazon S3 REST API 操作](#dsse-request-headers-kms)
+ [加密上下文（`x-amz-server-side-encryption-context`）](#s3-dsse-encryption-context)
+ [AWS KMS 密钥 ID（`x-amz-server-side-encryption-aws-kms-key-id`）](#s3-dsse-key-id-api)

### 支持 DSSE-KMS 的 Amazon S3 REST API 操作
<a name="dsse-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` 操作传递 DSSE-KMS 标头，它们仅应用于目标对象。复制现有对象时，不论源对象是否已经加密，都不会加密目标对象，除非您显式请求服务器端加密。
+ [POST Object](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) – 使用分段上传来上传大型对象时，可以在 `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)
+ [POST 对象](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` 请求，则这些请求都将失败。
如果对象使用 DSSE-KMS，则不应对 `GET` 请求和 `HEAD` 请求发送加密请求标头，否则您将得到 HTTP 400（错误请求）错误。

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

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

Amazon S3 自动使用对象的 Amazon 资源名称（ARN）作为加密上下文对；例如 `arn:aws:s3:::object_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-dsse-key-id-api"></a>

您可以使用 `x-amz-server-side-encryption-aws-kms-key-id` 标头指定用于保护数据的客户自主管理型密钥的 ID。如果您指定 `x-amz-server-side-encryption:aws:kms:dsse` 标头但未提供 `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)。

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

当您上传新对象或复制现有对象时，可以指定使用 DSSE-KMS 来加密数据。为此，请将 `--server-side-encryption aws:kms:dsse` 参数添加到请求。使用 `--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:dsse`，但未提供 AWS KMS 密钥 ID，则 Amazon S3 将使用 AWS 托管式密钥（`aws/s3`）。

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

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

```
aws s3api copy-object --bucket amzn-s3-demo-bucket --key example-object-key --copy-source amzn-s3-demo-bucket/example-object-key --server-side-encryption aws:kms:dsse --ssekms-key-id example-key-id
```

# 使用具有客户提供的密钥的服务器端加密（SSE-C）
<a name="ServerSideEncryptionCustomerKeys"></a>

服务器端加密是为了保护静态数据。服务器端加密仅加密对象数据而非加密对象元数据。您可以在通用存储桶中使用具有客户提供密钥的服务器端加密（SSE-C），通过自己的加密密钥来加密数据。使用您作为请求的一部分提供的加密密钥，Amazon S3 在其写入磁盘时管理数据加密，并在您访问对象时管理数据解密。因此，您不需要维护任何代码来执行数据加密和解密。您只需管理您提供的加密密钥。

Amazon S3 中的大多数现代化使用案例不再使用 SSE-C，因为相比具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）或具有 AWS KMS 密钥的服务器端加密（SSE-KMS），这种方法欠缺灵活性。SSE-C 要求您在每次与 SSE-C 加密数据交互时提供加密密钥，因此您无法通过与其他用户、角色或 AWS 服务共享 SSE-C 密钥来允许对方从您的 S3 存储桶读取数据以便操作数据。由于 AWS 广泛支持 SSE-KMS，大多数现代化工作负载都不使用 SSE-C 加密，因为此方法欠缺 SSE-KMS 的灵活性。要了解有关 SSE-KMS 的更多信息，请参阅[使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）](UsingKMSEncryption.md)。

如果您想阻止对写入存储桶的对象使用 SSE-C 加密，则可以在更改存储桶的默认加密配置时阻止 SSE-C 加密。为通用存储桶阻止了 SSE-C 之后，任何指定 SSE-C 加密的 `PutObject`、`CopyObject`、`PostObject`、分段上传或复制请求都将被拒绝，并返回 `HTTP 403 AccessDenied` 错误。要了解有关阻止 SSE-C 的更多信息，请参阅[对通用存储桶阻止或取消阻止 SSE-C](blocking-unblocking-s3-c-encryption-gpb.md)。

使用 SSE-C 没有额外费用。但是，配置和使用 SSE-C 的请求会产生标准的 Amazon S3 请求费用。有关定价的信息，请参阅 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)。

**重要**  
从 2026 年 4 月开始，AWS 将对所有新存储桶禁用具有客户提供密钥的服务器端加密（SSE-C）。此外，对于 AWS 账户中没有任何 SSE-C 加密数据的所有现有存储桶，都将禁用 SSE-C 加密。通过这些更改，少数需要 SSE-C 加密的应用程序必须在创建存储桶后，专门通过 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API 启用 SSE-C。在这些情况下，您可能需要更新自动化脚本、CloudFormation 模板或其他基础设施配置工具来配置这些设置。有关更多信息，请参阅 [AWS Storage 博客文章](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)。

## 使用 SSE-C 之前的注意事项
<a name="considerations-before-using-sse-c"></a>
+ 当您使用 SSE-C 时，S3 从不存储加密密钥。每次您要让任何人从 S3 下载您的 SSE-C 加密数据时，都必须提供加密密钥。
  + 您管理哪个加密密钥用于加密哪个对象的映射。您负责跟踪为哪个对象提供了哪个加密密钥。这还意味着，如果您丢失加密密钥，则会失去该对象。
  + 因为您在客户端管理加密密钥，所以也要在客户端管理所有额外的保护措施，例如密钥轮换。
  + 这种设计使您难以与其他用户、角色或 AWS 服务共享 SSE-C 密钥来操作您的数据。由于 AWS 广泛支持 SSE-KMS，大多数现代化工作负载都不使用 SSE-C，因为此方法欠缺 SSE-KMS 的灵活性。要了解有关 SSE-KMS 的更多信息，请参阅[使用具有 AWS KMS 密钥的服务器端加密（SSE-KMS）](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html)。
  + 这意味着 AWS 托管服务无法对使用 SSE-C 加密的对象进行本地解密。
+ 在请求中指定 SSE-C 标头时，必须使用 HTTPS。
  + 在使用 SSE-C 时，Amazon S3 会拒绝通过 HTTP 发出的所有请求。出于安全原因，我们建议您考虑您错误地通过 HTTP 发送的任何密钥都会遭泄露。丢弃该密钥，并根据需要轮换密钥。
+ 如果您的存储桶启用了版本控制，则您上传的每个对象版本可能都具有自己的加密密钥。您负责跟踪哪个加密密钥用于哪个对象版本。
+ Amazon S3 控制台中不支持 SSE-C。您不能使用 Amazon S3 控制台上传对象和指定 SSE-C 加密。也不能使用控制台来更新使用 SSE-C 存储的现有对象（例如，更改存储类别或添加元数据）。

**Topics**
+ [使用 SSE-C 之前的注意事项](#considerations-before-using-sse-c)
+ [指定使用客户提供的密钥的服务器端加密 (SSE-C)。](specifying-s3-c-encryption.md)
+ [对通用存储桶阻止或取消阻止 SSE-C](blocking-unblocking-s3-c-encryption-gpb.md)
+ [新存储桶的默认 SSE-C 设置常见问题解答](default-s3-c-encryption-setting-faq.md)

# 指定使用客户提供的密钥的服务器端加密 (SSE-C)。
<a name="specifying-s3-c-encryption"></a>

要使用具有客户提供密钥的服务器端加密（SSE-C），请先确保在您的 Amazon S3 通用存储桶默认加密配置中，没有阻止 SSE-C 加密类型。如果此加密类型被阻止，您可以通过更新存储桶的默认加密配置来启用它。然后，您可以通过在上传请求中传递所需的标头来使用 SSE-C。请参阅[支持使用 SSE-C 写入数据的 Amazon S3 操作](#amazon-s3-actions-that-support-writing-data-with-sse-c)，并确保包含 [SSE-C 对象加密和解密请求所需的 S3 API 标头](#s3-api-headers-required-for-sse-c-object-encryption-and-decryption-requests)。

如果您在上传对象时指定了 SSE-C，Amazon S3 将使用您提供的加密密钥对数据应用 AES-256 加密。然后，Amazon S3 从内存中删除此加密密钥。在检索对象时，必须提供相同的加密密钥作为您请求的一部分。Amazon S3 在将对象数据返回给您之前，会首先验证您提供的加密密钥是否匹配，然后再解密对象。

使用 SSE-C 之前，请确保您已查看[使用 SSE-C 之前的注意事项](ServerSideEncryptionCustomerKeys.md#considerations-before-using-sse-c)。

**注意**  
Amazon S3 不存储您提供的加密密钥，而是存储加密密钥的添加了随机数据的 HMAC 散列消息认证码（HMAC）值，以验证将来的请求。无法使用添加了随机数据的 HMAC 值来推导出加密密钥的值或解密加密对象的内容。这意味着，如果您丢失加密密钥，则会失去该对象。

**Topics**
+ [SSE-C 操作和必需表头](#sse-c-actions-and-required-headers)
+ [强制 SSE-C 加密的存储桶策略示例](#example-bucket-policy-to-enforce-sse-c-encryption)
+ [预签名 URL 和 SSE-C](#ssec-and-presignedurl)
+ [使用 SSE-C 发出请求](#making-requests-with-sse-c)
+ [使用 REST API](#using-rest-api-sse-c)
+ [使用 AWS SDK 为 PUT、GET、Head 和 Copy 操作指定 SSE-C](#sse-c-using-sdks)
+ [使用 AWS SDK 为分段上传指定 SSE-C](#sse-c-using-sdks-multipart-uploads)

## SSE-C 操作和必需表头
<a name="sse-c-actions-and-required-headers"></a>

在支持的 S3 API 上指定 SSE-C 需要传递特定请求参数。

**注意**  
Amazon S3 中的 `PutBucketEncryption` API 用于为存储桶配置默认的服务器端加密。但是，`PutBucketEncryption` 不支持启用 SSE-C 作为存储桶的默认加密方法。SSE-C 是对象级加密方法，您可以随对象上传或下载的每个请求向 Amazon S3 提供加密密钥。Amazon S3 在请求处理期间使用此密钥加密或解密对象，然后丢弃密钥。这意味着 SSE-C 是按对象启用的，而不是作为默认的存储桶设置。

### 支持使用 SSE-C 写入数据的 Amazon S3 操作
<a name="amazon-s3-actions-that-support-writing-data-with-sse-c"></a>

您可以使用以下 API 操作，在向通用存储桶写入对象时，请求使用具有客户提供密钥的服务器端加密（SSE-C）：
+ [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/API_CreateMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.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/RESTObjectPOST.html](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [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_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)

**注意**  
S3 复制支持使用 SSE-C 加密的对象。有关复制加密对象的更多信息，请参阅[复制加密对象（SSE-S3、SSE-KMS、DSSE-KMS、SSE-C）](replication-config-for-kms-objects.md)。

### SSE-C 对象加密和解密请求所需的 S3 API 标头
<a name="s3-api-headers-required-for-sse-c-object-encryption-and-decryption-requests"></a>

要使用 SSE-C 加密或解密对象，您必须提供以下三个 API 标头：
+ `x-amz-server-side-encryption-customer-algorithm`：使用此标头来指定加密算法。标头值必须为 AES256。
+ `x-amz-server-side-encryption-customer-key`：使用此标头来提供 256 位的 base64 编码的加密密钥，供 Amazon S3 用于加密或解密您的数据。
+ `x-amz-server-side-encryption-customer-key-MD5`：使用此标头来根据 RFC 1321，提供加密密钥的 base64 编码的 128 位 MD5 摘要。Amazon S3 使用此标头进行消息完整性检查以确保加密密钥的传输无误。

### 请求复制使用 SSE-C 加密的源对象时需要的 S3 API 标头
<a name="s3-api-headers-required-for-requests-to-copy-source-objects-encrypted-with-sse-c"></a>

要复制使用 SSE-C 加密的源对象，您必须提供以下三个 API 标头：
+ `x-amz-copy-source-server-side-encryption-customer-algorithm`：包括此标头以指定 Amazon S3 用于解密源对象的算法。此值必须为 AES256。
+ `x-amz-copy-source-server-side-encryption-customer-key`：包括此标头以提供 base64 编码的加密密钥，供 Amazon S3 用于解密源对象。此加密密钥必须是您在创建源对象时为 Amazon S3 提供的加密密钥。否则，Amazon S3 无法解密对象。
+ `x-amz-copy-source-server-side-encryption-customer-key-MD5`：包括此标头来根据 RFC 1321，提供加密密钥的 base64 编码的 128 位 MD5 摘要。

## 强制 SSE-C 加密的存储桶策略示例
<a name="example-bucket-policy-to-enforce-sse-c-encryption"></a>

如果要对写入 Amazon S3 存储桶中的所有对象要求使用 SSE-C 加密，您可以使用存储桶策略。例如，如果请求不包括用于请求 SSE-C 的 `x-amz-server-side-encryption-customer-algorithm` 标头，以下存储桶策略将拒绝针对所有此类请求的上传对象（`s3:PutObject`）权限。

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

**重要**  
如果您使用存储桶策略在 `s3:PutObject` 上请求 SSE-C，则必须在所有分段上传请求中（CreateMultipartUpload、UploadPart 和 CompleteMultipartUpload）包括 `x-amz-server-side-encryption-customer-algorithm` 标头。

## 预签名 URL 和 SSE-C
<a name="ssec-and-presignedurl"></a>

您可以生成可用于上传新对象、检索现有对象或检索对象元数据等操作的预签名 URL。预签名 URL 支持 SSE-C，如下所示：
+ 在创建预签名 URL 时，您必须在签名计算中使用 `x-amz-server-side-encryption-customer-algorithm` 标头指定算法。
+ 在使用预签名 URL 上传新对象、检索现有对象或仅检索对象元数据时，您必须在您的客户端应用程序的请求中提供所有加密标头。
**注意**  
对于非 SSE-C 对象，您可以生成预签名 URL，并将该 URL 直接复制到浏览器中以访问数据。  
但是，不能对 SSE-C 对象执行此操作，因为除了预签名 URL 外，还必须包含 SSE-C 对象特定的 HTTP 标头。因此，您只能以编程方式将预签名 URL 用于 SSE-C 对象。

有关预签名 URL 的更多信息，请参阅 [使用预签名 URL 下载和上传对象](using-presigned-url.md)。

## 使用 SSE-C 发出请求
<a name="making-requests-with-sse-c"></a>

 在使用 REST API 创建对象时，您可以使用客户提供的密钥（SSE-C）指定服务器端加密。使用 SSE-C 时，必须使用[请求复制使用 SSE-C 加密的源对象时需要的 S3 API 标头](#s3-api-headers-required-for-requests-to-copy-source-objects-encrypted-with-sse-c)提供加密密钥信息。您可以使用 AWS SDK 包装库将这些标头添加到您的请求中。如果需要，您可以直接在应用程序中调用 Amazon S3 REST API。

**重要**  
在指定具有客户提供密钥的服务器端加密（SSE-C）之前，请确保通用存储桶未阻止 SSE-C 加密。有关更多信息，请参阅 [对通用存储桶阻止或取消阻止 SSE-C](blocking-unblocking-s3-c-encryption-gpb.md)。

**注意**  
您不能使用 Amazon S3 控制台上传对象并请求 SSE-C，也不能使用控制台来更新使用 SSE-C 存储的现有对象（例如，更改存储类别或添加元数据）。有关更多信息，请参阅[SSE-C 对象加密和解密请求所需的 S3 API 标头](#s3-api-headers-required-for-sse-c-object-encryption-and-decryption-requests)。

## 使用 REST API
<a name="using-rest-api-sse-c"></a>

### 支持 SSE-C 的 Amazon S3 REST API
<a name="sse-c-supported-apis"></a>

以下 Amazon S3 API 支持使用客户提供的加密密钥进行服务器端加密 (SSE-C)。
+ **GET 操作** – 在使用 GET API 检索对象（请参阅 [GET Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html)）时，您可以指定请求标头。
+ **HEAD 操作** – 要使用 HEAD API 检索对象元数据（请参阅 [HEAD Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html)），可以指定这些请求标头。
+ **PUT 操作** – 使用 PUT Object API 上传数据（请参阅 [PUT Object](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)）时，可以指定这些请求标头。
+ **分段上传** – 在使用分段上传 API 上传大对象时，可以指定这些标头。您可以在以下请求中指定这些标头：启动请求（请参阅[启动分段上传](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)），以及每个后续分段上传请求（请参阅[上传分段](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html)或 [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html)）。对于每个分段上传请求，加密信息必须与您在启动分段上传请求中提供的信息相同。
+ **POST 操作** – 使用 POST 操作上传对象（请参阅 [POST 对象](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)）时，可在表单字段而不是请求标头中提供相同的信息。
+ **复制操作**：复制对象（请参阅 [CopyObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)）时，您同时具有源对象和目标对象：
  + 如果要指定目标对象的加密类型，您必须提供 `x-amz-server-side-encryption `请求标头。
  + 如果您希望使用 SSE-C 加密目标对象，则必须使用[SSE-C 对象加密和解密请求所需的 S3 API 标头](#s3-api-headers-required-for-sse-c-object-encryption-and-decryption-requests)提供加密信息。
  + 如果源对象使用 SSE-C 加密，则您必须使用[请求复制使用 SSE-C 加密的源对象时需要的 S3 API 标头](#s3-api-headers-required-for-requests-to-copy-source-objects-encrypted-with-sse-c)提供加密密钥信息。

## 使用 AWS SDK 为 PUT、GET、Head 和 Copy 操作指定 SSE-C
<a name="sse-c-using-sdks"></a>

以下示例演示如何为对象请求使用客户提供的密钥的服务器端加密 (SSE-C)。这些示例执行以下操作。每个操作均演示了如何在请求中指定 SSE-C 相关标头：
+ **放置对象** – 上传对象，并请求使用客户提供的加密密钥的服务器端加密。
+ **获取对象** – 下载上一步中上传的对象。在请求中，应提供上传对象时提供的同一加密信息。Amazon S3 需要此信息来解密对象，以便将对象返回给您。
+ **获取对象元数据** – 检索对象的元数据。提供创建对象时使用的同一加密信息。
+ **复制对象** – 复制之前上传的对象的副本。因为源对象是使用 SSE-C 存储的，因此必须在复制请求中提供其加密信息。默认情况下，仅当您显式请求加密时，Amazon S3 才会为对象的副本加密。此示例指示 Amazon S3 存储对象的加密副本。

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

**注意**  
本示例显示如何在单个操作中上传对象。当使用分段上传 API 上传大型对象时，应按照此示例中所示的方式提供加密信息。有关使用 适用于 Java 的 AWS SDK 的分段上传的示例，请参阅 [使用分段上传操作上传对象](mpu-upload-object.md)。

要添加必需的加密信息，请在请求中包含 `SSECustomerKey`。有关该 `SSECustomerKey` 课程的更多信息，请参阅 REST API 部分。

有关创建和测试有效示例的说明，请参阅《适用于 Java 的 AWS SDK 开发人员指南》中的[入门](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/getting-started.html)。

**Example**  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

import javax.crypto.KeyGenerator;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class ServerSideEncryptionUsingClientSideEncryptionKey {
    private static SSECustomerKey SSE_KEY;
    private static AmazonS3 S3_CLIENT;
    private static KeyGenerator KEY_GENERATOR;

    public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String keyName = "*** Key name ***";
        String uploadFileName = "*** File path ***";
        String targetKeyName = "*** Target key name ***";

        // Create an encryption key.
        KEY_GENERATOR = KeyGenerator.getInstance("AES");
        KEY_GENERATOR.init(256, new SecureRandom());
        SSE_KEY = new SSECustomerKey(KEY_GENERATOR.generateKey());

        try {
            S3_CLIENT = AmazonS3ClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(clientRegion)
                    .build();

            // Upload an object.
            uploadObject(bucketName, keyName, new File(uploadFileName));

            // Download the object.
            downloadObject(bucketName, keyName);

            // Verify that the object is properly encrypted by attempting to retrieve it
            // using the encryption key.
            retrieveObjectMetadata(bucketName, keyName);

            // Copy the object into a new object that also uses SSE-C.
            copyObject(bucketName, keyName, targetKeyName);
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }

    private static void uploadObject(String bucketName, String keyName, File file) {
        PutObjectRequest putRequest = new PutObjectRequest(bucketName, keyName, file).withSSECustomerKey(SSE_KEY);
        S3_CLIENT.putObject(putRequest);
        System.out.println("Object uploaded");
    }

    private static void downloadObject(String bucketName, String keyName) throws IOException {
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, keyName).withSSECustomerKey(SSE_KEY);
        S3Object object = S3_CLIENT.getObject(getObjectRequest);

        System.out.println("Object content: ");
        displayTextInputStream(object.getObjectContent());
    }

    private static void retrieveObjectMetadata(String bucketName, String keyName) {
        GetObjectMetadataRequest getMetadataRequest = new GetObjectMetadataRequest(bucketName, keyName)
                .withSSECustomerKey(SSE_KEY);
        ObjectMetadata objectMetadata = S3_CLIENT.getObjectMetadata(getMetadataRequest);
        System.out.println("Metadata retrieved. Object size: " + objectMetadata.getContentLength());
    }

    private static void copyObject(String bucketName, String keyName, String targetKeyName)
            throws NoSuchAlgorithmException {
        // Create a new encryption key for target so that the target is saved using
        // SSE-C.
        SSECustomerKey newSSEKey = new SSECustomerKey(KEY_GENERATOR.generateKey());

        CopyObjectRequest copyRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName)
                .withSourceSSECustomerKey(SSE_KEY)
                .withDestinationSSECustomerKey(newSSEKey);

        S3_CLIENT.copyObject(copyRequest);
        System.out.println("Object copied");
    }

    private static void displayTextInputStream(S3ObjectInputStream input) throws IOException {
        // Read one line at a time from the input stream and display each line.
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        System.out.println();
    }
}
```

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

**注意**  
有关使用分段上传 API 上传大型对象的示例，请参阅 [使用分段上传操作上传对象](mpu-upload-object.md) 和 [使用 AWS SDK（低级别 API）](mpu-upload-object.md#mpu-upload-low-level)。

有关设置和运行代码示例的信息，请参阅《适用于 .NET 的 AWS SDK 开发人员指南》**中的[适用于 .NET 的 AWS SDK 入门](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。

**Example**  

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class SSEClientEncryptionKeyObjectOperationsTest
    {
        private const string bucketName = "*** bucket name ***"; 
        private const string keyName = "*** key name for new object created ***"; 
        private const string copyTargetKeyName = "*** key name for object copy ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;

        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            ObjectOpsUsingClientEncryptionKeyAsync().Wait();
        }
        private static async Task ObjectOpsUsingClientEncryptionKeyAsync()
        {
            try
            {
                // Create an encryption key.
                Aes aesEncryption = Aes.Create();
                aesEncryption.KeySize = 256;
                aesEncryption.GenerateKey();
                string base64Key = Convert.ToBase64String(aesEncryption.Key);

                // 1. Upload the object.
                PutObjectRequest putObjectRequest = await UploadObjectAsync(base64Key);
                // 2. Download the object and verify that its contents matches what you uploaded.
                await DownloadObjectAsync(base64Key, putObjectRequest);
                // 3. Get object metadata and verify that the object uses AES-256 encryption.
                await GetObjectMetadataAsync(base64Key);
                // 4. Copy both the source and target objects using server-side encryption with 
                //    a customer-provided encryption key.
                await CopyObjectAsync(aesEncryption, base64Key);
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        }

        private static async Task<PutObjectRequest> UploadObjectAsync(string base64Key)
        {
            PutObjectRequest putObjectRequest = new PutObjectRequest
            {
                BucketName = bucketName,
                Key = keyName,
                ContentBody = "sample text",
                ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                ServerSideEncryptionCustomerProvidedKey = base64Key
            };
            PutObjectResponse putObjectResponse = await client.PutObjectAsync(putObjectRequest);
            return putObjectRequest;
        }
        private static async Task DownloadObjectAsync(string base64Key, PutObjectRequest putObjectRequest)
        {
            GetObjectRequest getObjectRequest = new GetObjectRequest
            {
                BucketName = bucketName,
                Key = keyName,
                // Provide encryption information for the object stored in Amazon S3.
                ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                ServerSideEncryptionCustomerProvidedKey = base64Key
            };

            using (GetObjectResponse getResponse = await client.GetObjectAsync(getObjectRequest))
            using (StreamReader reader = new StreamReader(getResponse.ResponseStream))
            {
                string content = reader.ReadToEnd();
                if (String.Compare(putObjectRequest.ContentBody, content) == 0)
                    Console.WriteLine("Object content is same as we uploaded");
                else
                    Console.WriteLine("Error...Object content is not same.");

                if (getResponse.ServerSideEncryptionCustomerMethod == ServerSideEncryptionCustomerMethod.AES256)
                    Console.WriteLine("Object encryption method is AES256, same as we set");
                else
                    Console.WriteLine("Error...Object encryption method is not the same as AES256 we set");

                // Assert.AreEqual(putObjectRequest.ContentBody, content);
                // Assert.AreEqual(ServerSideEncryptionCustomerMethod.AES256, getResponse.ServerSideEncryptionCustomerMethod);
            }
        }
        private static async Task GetObjectMetadataAsync(string base64Key)
        {
            GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest
            {
                BucketName = bucketName,
                Key = keyName,

                // The object stored in Amazon S3 is encrypted, so provide the necessary encryption information.
                ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                ServerSideEncryptionCustomerProvidedKey = base64Key
            };

            GetObjectMetadataResponse getObjectMetadataResponse = await client.GetObjectMetadataAsync(getObjectMetadataRequest);
            Console.WriteLine("The object metadata show encryption method used is: {0}", getObjectMetadataResponse.ServerSideEncryptionCustomerMethod);
            // Assert.AreEqual(ServerSideEncryptionCustomerMethod.AES256, getObjectMetadataResponse.ServerSideEncryptionCustomerMethod);
        }
        private static async Task CopyObjectAsync(Aes aesEncryption, string base64Key)
        {
            aesEncryption.GenerateKey();
            string copyBase64Key = Convert.ToBase64String(aesEncryption.Key);

            CopyObjectRequest copyRequest = new CopyObjectRequest
            {
                SourceBucket = bucketName,
                SourceKey = keyName,
                DestinationBucket = bucketName,
                DestinationKey = copyTargetKeyName,
                // Information about the source object's encryption.
                CopySourceServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                CopySourceServerSideEncryptionCustomerProvidedKey = base64Key,
                // Information about the target object's encryption.
                ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                ServerSideEncryptionCustomerProvidedKey = copyBase64Key
            };
            await client.CopyObjectAsync(copyRequest);
        }
    }
}
```

------

## 使用 AWS SDK 为分段上传指定 SSE-C
<a name="sse-c-using-sdks-multipart-uploads"></a>

上一部分中的示例显示了如何在 PUT、GET、Head 和 Copy 操作中请求使用客户提供的密钥的服务器端加密 (SSE-C)。本节介绍支持 SSE-C 的其他 Amazon S3 API。

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

要上传大型对象，您可以使用分段上传 API。有关更多信息，请参阅 [在 Amazon S3 中使用分段上传来上传和复制对象](mpuoverview.md)。可以使用高级或低级 API 上传大型对象。这些 API 支持在请求中使用与加密相关的标头。
+ 使用高级别 `TransferManager` API 时，应在 `PutObjectRequest` 中提供特定于加密的标头。有关更多信息，请参阅 [使用分段上传操作上传对象](mpu-upload-object.md)。
+ 当使用低级别 API 时，应提供 `InitiateMultipartUploadRequest` 中的加密相关信息，后跟每个 `UploadPartRequest` 中的相同加密信息。不需要在 `CompleteMultipartUploadRequest` 中提供任何特定于加密的标头。有关示例，请参阅 [使用 AWS SDK（低级别 API）](mpu-upload-object.md#mpu-upload-low-level)。

以下示例使用 `TransferManager` 创建对象并显示如何提供 SSE-C 相关信息。本示例执行以下操作：
+ 使用 `TransferManager.upload()` 方法创建对象。在 `PutObjectRequest` 实例中，应在请求中提供加密密钥信息。Amazon S3 将使用客户提供的密钥对于对象进行加密。
+ 通过调用 `TransferManager.copy()` 方法创建对象的副本。该示例指示 Amazon S3 使用新的 `SSECustomerKey` 对对象副本进行加密。由于源对象使用 SSE-C 加密，因此 `CopyObjectRequest` 还提供了源对象的加密密钥，以便 Amazon S3 可以在复制对象之前解密对象。

**Example**  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.SSECustomerKey;
import com.amazonaws.services.s3.transfer.Copy;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;

import javax.crypto.KeyGenerator;
import java.io.File;
import java.security.SecureRandom;

public class ServerSideEncryptionCopyObjectUsingHLwithSSEC {

    public static void main(String[] args) throws Exception {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String fileToUpload = "*** File path ***";
        String keyName = "*** New object key name ***";
        String targetKeyName = "*** Key name for object copy ***";

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();
            TransferManager tm = TransferManagerBuilder.standard()
                    .withS3Client(s3Client)
                    .build();

            // Create an object from a file.
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, keyName, new File(fileToUpload));

            // Create an encryption key.
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(256, new SecureRandom());
            SSECustomerKey sseCustomerEncryptionKey = new SSECustomerKey(keyGenerator.generateKey());

            // Upload the object. TransferManager uploads asynchronously, so this call
            // returns immediately.
            putObjectRequest.setSSECustomerKey(sseCustomerEncryptionKey);
            Upload upload = tm.upload(putObjectRequest);

            // Optionally, wait for the upload to finish before continuing.
            upload.waitForCompletion();
            System.out.println("Object created.");

            // Copy the object and store the copy using SSE-C with a new key.
            CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName);
            SSECustomerKey sseTargetObjectEncryptionKey = new SSECustomerKey(keyGenerator.generateKey());
            copyObjectRequest.setSourceSSECustomerKey(sseCustomerEncryptionKey);
            copyObjectRequest.setDestinationSSECustomerKey(sseTargetObjectEncryptionKey);

            // Copy the object. TransferManager copies asynchronously, so this call returns
            // immediately.
            Copy copy = tm.copy(copyObjectRequest);

            // Optionally, wait for the upload to finish before continuing.
            copy.waitForCompletion();
            System.out.println("Copy complete.");
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }
}
```

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

要上传大型对象，您可以使用分段上传 API（请参阅[在 Amazon S3 中使用分段上传来上传和复制对象](mpuoverview.md)）。AWS适用于 .NET 的 SDK 提供了高级或低级 API 来上传大型对象。这些 API 支持在请求中使用与加密相关的标头。
+ 当使用高级 `Transfer-Utility ` API 时，可以在 `TransferUtilityUploadRequest` 中提供特定于加密的标头，如下所示。有关代码示例，请参阅 [使用分段上传操作上传对象](mpu-upload-object.md)。

  ```
  TransferUtilityUploadRequest request = new TransferUtilityUploadRequest()
  {
      FilePath = filePath,
      BucketName = existingBucketName,
      Key = keyName,
      // Provide encryption information.
      ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
      ServerSideEncryptionCustomerProvidedKey = base64Key,
  };
  ```
+ 当使用低级 API 时，可以在启动分段上传请求中提供加密相关的信息，并在后续的分段上传请求中提供相同加密信息。不需要在完成的分段上传请求中提供任何特定于加密的标头。有关示例，请参阅 [使用 AWS SDK（低级别 API）](mpu-upload-object.md#mpu-upload-low-level)。

  下面是一个低级分段上传示例，该示例复制一个现有大型对象。在本示例中，要复制的对象使用 SSE-C 存储在 Amazon S3 中，并且您希望使用 SSE-C 保存目标对象。在本例中，您可以执行以下操作：
  + 通过提供加密密钥和相关信息启动分段上传请求。
  + 在 `CopyPartRequest` 中提供源和目标对象加密密钥及相关信息。
  + 通过检索对象元数据获取要复制的源对象的大小。
  + 以 5 MB 大小的分段上传对象。  
**Example**  

  ```
  using Amazon;
  using Amazon.S3;
  using Amazon.S3.Model;
  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Security.Cryptography;
  using System.Threading.Tasks;
  
  namespace Amazon.DocSamples.S3
  {
      class SSECLowLevelMPUcopyObjectTest
      {
          private const string existingBucketName = "*** bucket name ***";
          private const string sourceKeyName      = "*** source object key name ***"; 
          private const string targetKeyName      = "*** key name for the target object ***";
          private const string filePath           = @"*** file path ***";
          // Specify your bucket region (an example region is shown).
          private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
          private static IAmazonS3 s3Client;
          static void Main()
          {
              s3Client = new AmazonS3Client(bucketRegion);
              CopyObjClientEncryptionKeyAsync().Wait();
          }
  
          private static async Task CopyObjClientEncryptionKeyAsync()
          {
              Aes aesEncryption = Aes.Create();
              aesEncryption.KeySize = 256;
              aesEncryption.GenerateKey();
              string base64Key = Convert.ToBase64String(aesEncryption.Key);
  
              await CreateSampleObjUsingClientEncryptionKeyAsync(base64Key, s3Client);
  
              await CopyObjectAsync(s3Client, base64Key);
          }
          private static async Task CopyObjectAsync(IAmazonS3 s3Client, string base64Key)
          {
              List<CopyPartResponse> uploadResponses = new List<CopyPartResponse>();
  
              // 1. Initialize.
              InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest
              {
                  BucketName = existingBucketName,
                  Key = targetKeyName,
                  ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                  ServerSideEncryptionCustomerProvidedKey = base64Key,
              };
  
              InitiateMultipartUploadResponse initResponse =
                  await s3Client.InitiateMultipartUploadAsync(initiateRequest);
  
              // 2. Upload Parts.
              long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB
              long firstByte = 0;
              long lastByte = partSize;
  
              try
              {
                  // First find source object size. Because object is stored encrypted with
                  // customer provided key you need to provide encryption information in your request.
                  GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest()
                  {
                      BucketName = existingBucketName,
                      Key = sourceKeyName,
                      ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                      ServerSideEncryptionCustomerProvidedKey = base64Key // " * **source object encryption key ***"
                  };
  
                  GetObjectMetadataResponse getObjectMetadataResponse = await s3Client.GetObjectMetadataAsync(getObjectMetadataRequest);
  
                  long filePosition = 0;
                  for (int i = 1; filePosition < getObjectMetadataResponse.ContentLength; i++)
                  {
                      CopyPartRequest copyPartRequest = new CopyPartRequest
                      {
                          UploadId = initResponse.UploadId,
                          // Source.
                          SourceBucket = existingBucketName,
                          SourceKey = sourceKeyName,
                          // Source object is stored using SSE-C. Provide encryption information.
                          CopySourceServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                          CopySourceServerSideEncryptionCustomerProvidedKey = base64Key, //"***source object encryption key ***",
                          FirstByte = firstByte,
                          // If the last part is smaller then our normal part size then use the remaining size.
                          LastByte = lastByte > getObjectMetadataResponse.ContentLength ?
                              getObjectMetadataResponse.ContentLength - 1 : lastByte,
  
                          // Target.
                          DestinationBucket = existingBucketName,
                          DestinationKey = targetKeyName,
                          PartNumber = i,
                          // Encryption information for the target object.
                          ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                          ServerSideEncryptionCustomerProvidedKey = base64Key
                      };
                      uploadResponses.Add(await s3Client.CopyPartAsync(copyPartRequest));
                      filePosition += partSize;
                      firstByte += partSize;
                      lastByte += partSize;
                  }
  
                  // Step 3: complete.
                  CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest
                  {
                      BucketName = existingBucketName,
                      Key = targetKeyName,
                      UploadId = initResponse.UploadId,
                  };
                  completeRequest.AddPartETags(uploadResponses);
  
                  CompleteMultipartUploadResponse completeUploadResponse =
                      await s3Client.CompleteMultipartUploadAsync(completeRequest);
              }
              catch (Exception exception)
              {
                  Console.WriteLine("Exception occurred: {0}", exception.Message);
                  AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest
                  {
                      BucketName = existingBucketName,
                      Key = targetKeyName,
                      UploadId = initResponse.UploadId
                  };
                  s3Client.AbortMultipartUpload(abortMPURequest);
              }
          }
          private static async Task CreateSampleObjUsingClientEncryptionKeyAsync(string base64Key, IAmazonS3 s3Client)
          {
              // List to store upload part responses.
              List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>();
  
              // 1. Initialize.
              InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest
              {
                  BucketName = existingBucketName,
                  Key = sourceKeyName,
                  ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                  ServerSideEncryptionCustomerProvidedKey = base64Key
              };
  
              InitiateMultipartUploadResponse initResponse =
                 await s3Client.InitiateMultipartUploadAsync(initiateRequest);
  
              // 2. Upload Parts.
              long contentLength = new FileInfo(filePath).Length;
              long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB
  
              try
              {
                  long filePosition = 0;
                  for (int i = 1; filePosition < contentLength; i++)
                  {
                      UploadPartRequest uploadRequest = new UploadPartRequest
                      {
                          BucketName = existingBucketName,
                          Key = sourceKeyName,
                          UploadId = initResponse.UploadId,
                          PartNumber = i,
                          PartSize = partSize,
                          FilePosition = filePosition,
                          FilePath = filePath,
                          ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
                          ServerSideEncryptionCustomerProvidedKey = base64Key
                      };
  
                      // Upload part and add response to our list.
                      uploadResponses.Add(await s3Client.UploadPartAsync(uploadRequest));
  
                      filePosition += partSize;
                  }
  
                  // Step 3: complete.
                  CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest
                  {
                      BucketName = existingBucketName,
                      Key = sourceKeyName,
                      UploadId = initResponse.UploadId,
                      //PartETags = new List<PartETag>(uploadResponses)
  
                  };
                  completeRequest.AddPartETags(uploadResponses);
  
                  CompleteMultipartUploadResponse completeUploadResponse =
                      await s3Client.CompleteMultipartUploadAsync(completeRequest);
  
              }
              catch (Exception exception)
              {
                  Console.WriteLine("Exception occurred: {0}", exception.Message);
                  AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest
                  {
                      BucketName = existingBucketName,
                      Key = sourceKeyName,
                      UploadId = initResponse.UploadId
                  };
                  await s3Client.AbortMultipartUploadAsync(abortMPURequest);
              }
          }
      }
  }
  ```

------

# 对通用存储桶阻止或取消阻止 SSE-C
<a name="blocking-unblocking-s3-c-encryption-gpb"></a>

Amazon S3 中的大多数现代化使用案例不再使用具有客户提供密钥的服务器端加密（SSE-C），因为相比具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）或具有 AWS KMS 密钥的服务器端加密（SSE-KMS），这种方法欠缺灵活性。SSE-C 要求您在每次与 SSE-C 加密数据交互时提供加密密钥，因此您无法通过与其他用户、角色或 AWS 服务共享 SSE-C 密钥来允许对方从您的 S3 存储桶读取数据以便操作数据。

要限制可在通用存储桶中使用的服务器端加密类型，您可以选择更新存储桶的默认加密配置，以此来阻止 SSE-C 写入请求。此存储桶级别的配置将阻止请求上传指定了 SSE-C 的对象。当存储桶阻止 SSE-C 时，任何指定了 SSE-C 加密的 `PutObject`、`CopyObject`、`PostObject`、分段上传或复制请求都将被拒绝，并返回 HTTP 403 `AccessDenied` 错误。

此设置是 `PutBucketEncryption` API 上的一个参数，如果您有 `s3:PutEncryptionConfiguration` 权限，也可以使用 S3 控制台、AWS CLI 和AWS SDK 更新此设置。

有效值为 `SSE-C`（在通用存储桶上阻止 SSE-C 加密）和 `NONE`（允许在写入存储桶时使用 SSE-C）。

**重要**  
从 2026 年 4 月开始，AWS 将对所有新存储桶禁用具有客户提供密钥的服务器端加密（SSE-C）。此外，对于 AWS 账户中没有任何 SSE-C 加密数据的所有现有存储桶，都将禁用 SSE-C 加密。通过这些更改，少数需要 SSE-C 加密的应用程序必须在创建存储桶后，专门通过 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API 启用 SSE-C。在这些情况下，您可能需要更新自动化脚本、CloudFormation 模板或其他基础设施配置工具来配置这些设置。有关更多信息，请参阅 [AWS Storage 博客文章](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)。

## 权限
<a name="bucket-encryption-permissions"></a>

对于通用存储桶，使用 `PutBucketEncryption` API、S3 控制台、AWS SDK 或 AWS CLI 来阻止或取消阻止加密类型。您必须拥有以下权限：
+ `s3:PutEncryptionConfiguration`

对于通用存储桶，使用 `GetBucketEncryption` API、S3 控制台、AWS SDK 或 AWS CLI 来查看阻止的加密类型。您必须拥有以下权限：
+ `s3:GetEncryptionConfiguration`

## 阻止 SSE-C 加密之前的注意事项
<a name="considerations-before-blocking-sse-c"></a>

在为所有存储桶阻止 SSE-C 后，将应用以下加密行为：
+ 对于在您阻止 SSE-C 加密之前存储桶中已有的对象，其加密没有变化。
+ 阻止 SSE-C 加密后，只要您在请求中提供所需的 SSE-C 标头，就可以继续对之前已有的 SSE-C 加密对象发出 GetObject 和 HeadObject 请求。
+ 为存储桶阻止 SSE-C 之后，任何指定 SSE-C 加密的 `PutObject`、`CopyObject`、`PostObject` 或分段上传请求都将被拒绝，并返回 HTTP 403 `AccessDenied` 错误。
+ 如果用于复制的目标存储桶已阻止 SSE-C，并且所复制的源对象使用 SSE-C 加密，则复制将失败并返回 HTTP 403 `AccessDenied` 错误。

如果您要在阻止 SSE-C 加密类型之前检查是否有任何存储桶使用了此加密类型，可以使用 [AWS CloudTrail](https://aws.amazon.com/cloudtrail/) 等工具来监控对数据的访问权限。这篇[博客文章](https://aws.amazon.com/blogs/storage/auditing-amazon-s3-server-side-encryption-methods-for-object-uploads/)说明如何实时审计对象上传的加密方法。您也可以参考这篇 [re:Post 文章](https://repost.aws/articles/ARhGC12rOiTBCKHcAe9GZXCA/how-to-detect-existing-use-of-sse-c-in-your-amazon-s3-buckets)，文中指导您通过查询 S3 清单报告来查看是否有任何 SSE-C 加密对象。

### Steps
<a name="block-sse-c-gpb-steps"></a>

对于通用存储桶，您可以使用 Amazon S3 控制台、AWS Command Line Interface（AWS CLI）、Amazon S3 REST API 和 AWS SDK，阻止或取消阻止具有客户提供密钥的服务器端加密（SSE-C）。

### 使用 S3 控制台
<a name="block-sse-c-gpb-console"></a>

要使用 Amazon S3 控制台为存储桶阻止或取消阻止 SSE-C 加密，请执行以下操作：

1. 登录 AWS 管理控制台并在 https://console.aws.amazon.com/s3/ 中打开 Amazon S3 控制台。

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

1. 选择您要阻止 SSE-C 加密的存储桶。

1. 选择存储桶的**属性**选项卡。

1. 导航到存储桶的**默认加密**属性面板，然后选择**编辑**。

1. 在**阻止的加密类型**部分中，选中**具有客户提供密钥的服务器端加密（SSE-C）**旁边的复选框可阻止 SSE-C 加密，取消选中此框则表示允许 SSE-C。

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

### 使用 AWS CLI
<a name="block-sse-c-gpb-cli"></a>

要安装 AWS CLI，请参阅《AWS Command Line Interface 用户指南》**中的[安装 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

以下 CLI 示例说明如何使用 AWS CLI，为通用存储桶阻止或取消阻止 SSE-C 加密。要使用该命令，请将*用户输入占位符* 替换为您自己的信息。

**请求为通用存储桶阻止 SSE-C 加密：**

```
aws s3api put-bucket-encryption \
  --bucket amzn-s3-demo-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "BlockEncryptionTypes": {
        "EncryptionType": "SSE-C"
      }
    }]
  }'
```

**请求在通用存储桶上启用 SSE-C 加密：**

```
aws s3api put-bucket-encryption \
  --bucket amzn-s3-demo-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "BlockEncryptionTypes": {
        "EncryptionType": "NONE"
      }
    }]
  }'
```

## 使用 AWS SDK
<a name="block-sse-c-gpb-sdks"></a>

------
#### [ SDK for Java 2.x ]

以下示例说明如何使用 AWS SDK，为通用存储桶阻止或取消阻止 SSE-C 加密写入。

**示例：PutBucketEncryption 请求将默认加密配置设置为 SSE-S3 并阻止 SSE-C**

```
S3Client s3Client = ...;
ServerSideEncryptionByDefault defaultSse = ServerSideEncryptionByDefault
        .builder()
        .sseAlgorithm(ServerSideEncryption.AES256)
        .build();
BlockedEncryptionTypes blockedEncryptionTypes = BlockedEncryptionTypes
        .builder()
        .encryptionType(EncryptionType.SSE_C)
        .build();
ServerSideEncryptionRule rule = ServerSideEncryptionRule.builder()
        .applyServerSideEncryptionByDefault(defaultSse)
        .blockedEncryptionTypes(blockedEncryptionTypes)
        .build();
s3Client.putBucketEncryption(be -> be
        .bucket(bucketName)
        .serverSideEncryptionConfiguration(c -> c.rules(rule)));
```

**示例：PutBucketEncryption 请求将默认加密配置设置为 SSE-S3 并取消阻止 SSE-C**

```
S3Client s3Client = ...;
ServerSideEncryptionByDefault defaultSse = ServerSideEncryptionByDefault
        .builder()
        .sseAlgorithm(ServerSideEncryption.AES256)
        .build();
BlockedEncryptionTypes blockedEncryptionTypes = BlockedEncryptionTypes
        .builder()
        .encryptionType(EncryptionType.NONE)
        .build();
ServerSideEncryptionRule rule = ServerSideEncryptionRule.builder()
        .applyServerSideEncryptionByDefault(defaultSse)
        .blockedEncryptionTypes(blockedEncryptionTypes)
        .build();
s3Client.putBucketEncryption(be -> be
        .bucket(bucketName)
        .serverSideEncryptionConfiguration(c -> c.rules(rule)));
```

------
#### [ SDK for Python Boto3 ]

**示例：PutBucketEncryption 请求将默认加密配置设置为 SSE-S3 并阻止 SSE-C**

```
s3 = boto3.client("s3")
s3.put_bucket_encryption(
    Bucket="amzn-s3-demo-bucket",
    ServerSideEncryptionConfiguration={
        "Rules":[{
            "ApplyServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
            },
            "BlockedEncryptionTypes": {
                "EncryptionType": ["SSE-C"]
            }
        }]
    }
)
```

**示例：PutBucketEncryption 请求将默认加密配置设置为 SSE-S3 并取消阻止 SSE-C**

```
s3 = boto3.client("s3")
s3.put_bucket_encryption(
    Bucket="amzn-s3-demo-bucket",
    ServerSideEncryptionConfiguration={
        "Rules":[{
            "ApplyServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
            },
            "BlockedEncryptionTypes": {
                "EncryptionType": ["NONE"]
            }
        }]
    }
)
```

------

## 使用 REST API
<a name="bucket-tag-add-api"></a>

有关 Amazon S3 REST API 支持为通用存储桶阻止或取消阻止 SSE-C 加密的相关信息，请参阅《Amazon Simple Storage Service API 参考》**中的以下部分：
+ [BlockedEncryptionTypes](https://docs.aws.amazon.com/AmazonS3/latest/API/API_BlockedEncryptionTypes.html) 数据类型用于 [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) 和 [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) API 操作的 [ServerSideEncryptionRule](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ServerSideEncryptionRule.html) 数据类型中。

# 新存储桶的默认 SSE-C 设置常见问题解答
<a name="default-s3-c-encryption-setting-faq"></a>

**重要**  
从 2026 年 4 月开始，AWS 将对所有新存储桶禁用具有客户提供密钥的服务器端加密（SSE-C）。此外，对于 AWS 账户中没有任何 SSE-C 加密数据的所有现有存储桶，都将禁用 SSE-C 加密。通过这些更改，少数需要 SSE-C 加密的应用程序必须在创建存储桶后，专门通过 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API 启用 SSE-C。在这些情况下，您可能需要更新自动化脚本、CloudFormation 模板或其他基础设施配置工具来配置这些设置。有关更多信息，请参阅 [AWS Storage 博客文章](https://aws.amazon.com/blogs/storage/advanced-notice-amazon-s3-to-disable-the-use-of-sse-c-encryption-by-default-for-all-new-buckets-and-select-existing-buckets-in-april-2026/)。

以下各部分回答了有关此更新的问题。

**1. 2026 年 4 月，新的 SSE-C 设置是否会对所有新创建的存储桶生效？**

可以。在 2026 年 4 月期间，新的默认设置将逐步在所有 AWS 区域推出。

**2. 这次推出需要多长时间才能涵盖所有 AWS 区域？**

此更新将需要数周时间才能推出。当我们开始部署此更新时，我们将发布一篇“新增内容”帖子。

**3. 我怎么知道更新已完成？**

您可以创建新的存储桶，然后调用 [GetBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) API 操作来确定是否已禁用 SSE-C 加密，从而轻松地确定您所在的 AWS 区域是否已完成更改。更新完成后，默认情况下，所有新的通用存储桶都将自动禁用 SSE-C 加密。您可以在创建 S3 存储桶后，通过调用 [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API 操作调整这些设置。

**4. Amazon S3 会更新我现有的桶配置吗？**

如果您的 AWS 账户中没有任何 SSE-C 加密对象，则 AWS 将在所有现有存储桶上禁用 SSE-C 加密。如果您的 AWS 账户中的所有存储桶都包含 SSE-C 加密对象，则 AWS 不会更改该账户中任何存储桶的存储桶配置。您所在 AWS 区域的 `CreateBucket` 更改完成后，新的默认设置将应用于所有新的通用存储桶。

 **5. 我能否在更新完成之前对存储桶禁用 SSE-C 加密？** 

可以。您可以调用 [PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) API 操作并指定新的 `BlockedEncryptionTypes` 标头，为所有存储桶禁用 SSE-C 加密。

**6. 我能否使用 SSE-C 对新存储桶中的数据进行加密？**

可以。Amazon S3 中的大多数现代化使用案例不再使用 SSE-C，因为相比具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）或具有 AWS KMS 密钥的服务器端加密（SSE-KMS），这种方法欠缺灵活性。如果您需要在新存储桶中使用 SSE-C 加密，则可以创建新的存储桶，然后在单独的 `PutBucketEncryption` 请求中启用 SSE-C 加密。

 **示例**

```
aws s3api create-bucket \  
bucket amzn-s3-demo-bucket \ 
region us-east-1 \ 
  
aws s3api put-bucket-encryption \  
-- bucket amzn-s3-demo-bucket \
-- server-side-encryption-configuration \
'{ \Rules\: [{   
   {   
   \ApplyServerSideEncryptionByDefault\: {   
     \SSEAlgorithm\: \AES256\,  
    },   
   \BlockedEncryptionTypes\: [  
     \EncryptionType\:\NONE\]   
   }   
   }]   
}'
```

**注意**  
您必须拥有调用 `PutBucketEncryption` API 的 `s3:PutEncryptionConfiguration` 权限。

**7. 阻止 SSE-C 会如何影响对我的存储桶的请求？**

为存储桶阻止了 SSE-C 之后，任何指定 SSE-C 加密的 `PutObject`、`CopyObject`、`PostObject` 或者分段上传或复制请求都将被拒绝，并返回 HTTP 403 `AccessDenied` 错误。

# 使用客户端加密保护数据
<a name="UsingClientSideEncryption"></a>

*客户端加密*是在本地加密数据，以帮助确保数据在传输中和静态时的安全性的行为。要在将对象发送到 Amazon S3 之前对其进行加密，请使用 Amazon S3 加密客户端。当您的对象以这种方式加密时，您的对象不会泄露给任何第三方，包括 AWS。Amazon S3 接收已经加密的对象；Amazon S3 在加密或解密对象方面不起作用。您可以使用 Amazon S3 加密客户端和[服务器端加密](serv-side-encryption.md)来加密您的数据。当您向 Amazon S3 发送加密对象时，Amazon S3 无法将这些对象识别为已加密，它只会检测典型的对象。

Amazon S3 加密客户端充当您与 Amazon S3 之间的中介。在您实例化 Amazon S3 加密客户端后，您的对象将作为 Amazon S3 `PutObject` 和 `GetObject` 请求的一部分自动加密和解密。您的对象全部使用唯一的数据密钥加密。即使您将 KMS 密钥指定为包装密钥，Amazon S3 加密客户端也不会使用存储桶密钥或与存储桶密钥交互。

《Amazon S3 Encryption Client Developer Guide》**侧重于 3.0 及更高版本的 Amazon S3 加密客户端。有关更多信息，请参阅《Amazon S3 加密客户端开发人员指南》**中的[什么是 Amazon S3 加密客户端？](https://docs.aws.amazon.com//amazon-s3-encryption-client/latest/developerguide/what-is-s3-encryption-client.html)

有关早期版本的 Amazon S3 加密客户端的更多信息，请参阅适用于您的编程语言的《AWS SDK Developer Guide》。
+ [适用于 Java 的 AWS SDK](https://docs.aws.amazon.com//sdk-for-java/v1/developer-guide/examples-crypto.html)
+ [适用于 .NET 的 AWS SDK](https://docs.aws.amazon.com//sdk-for-net/v3/developer-guide/kms-keys-s3-encryption.html)
+ [适用于 Go 的 AWS SDK](https://docs.aws.amazon.com//sdk-for-go/v1/developer-guide/welcome.html)
+ [适用于 PHP 的 AWS SDK](https://docs.aws.amazon.com//sdk-for-php/v3/developer-guide/s3-encryption-client.html)
+ [适用于 Ruby 的 AWS SDK](https://docs.aws.amazon.com//sdk-for-ruby/v3/api/Aws/S3/Encryption.html)
+ [适用于 C\$1\$1 的 AWS SDK](https://docs.aws.amazon.com//sdk-for-cpp/v1/developer-guide/welcome.html)

# 利用加密来保护传输中数据
<a name="UsingEncryptionInTransit"></a>

Amazon S3 的数据传输支持 HTTP 和 HTTPS 两种协议。HTTP 以纯文本格式传输数据，而 HTTPS 则通过使用传输层安全性协议（TLS）加密数据增加了一层安全保护。TLS 可防止侦听、数据篡改和中间人攻击。虽然可以接受 HTTP 流量，但大多数实施都使用 HTTPS 和 TLS 进行传输中加密，来保护在客户端和 Amazon S3 之间传输的数据。

## TLS 1.2 和 TLS 1.3 支持
<a name="UsingEncryptionInTransit.TLS-support"></a>

对于所有 AWS 区域的所有 API 端点，Amazon S3 支持 HTTPS 连接的 TLS 1.2 和 TLS 1.3。S3 会自动协商您的客户端软件和所访问 S3 端点支持的最强 TLS 保护。当前 AWS 工具（2014 年及以后）包括 AWS SDK，AWS CLI 自动默认使用 TLS 1.3，无需您采取任何操作。如果需要向后兼容 TLS 1.2，您可以通过客户端配置设置指定特定的 TLS 版本，来覆盖此自动协商。使用 TLS 1.3 时，您可以选择配置混合后量子密钥交换（ML-KEM），向 Amazon S3 发出抗量子请求。有关更多信息，请参阅 [为客户端配置混合后量子 TLS](pqtls-how-to.md)。

**注意**  
除了适用于 Amazon S3 的 AWS PrivateLink 和多区域接入点之外，所有 S3 端点均支持 TLS 1.3。

## 监控 TLS 使用情况
<a name="UsingEncryptionInTransit.monitoring"></a>

您可以使用 Amazon S3 服务器访问日志或 AWS CloudTrail 来监控对 Amazon S3 存储桶的请求。两个日志记录选项都记录每个请求中使用的 TLS 版本和密码套件。
+ **Amazon S3 服务器访问日志**：服务器访问日志记录提供对存储桶发出的请求的详细报告。例如，访问日志信息可能在安全和访问权限审核方面很有用。有关更多信息，请参阅 [Amazon S3 服务器访问日志格式](LogFormat.md)。
+ **AWS CloudTrail**：[AWS CloudTrail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html) 是提供用户、角色或 AWS 服务所执行操作的记录的服务。CloudTrail 将 Amazon S3 的所有 API 调用作为事件捕获。有关更多信息，请参阅 [Amazon S3 CloudTrail 事件](cloudtrail-logging-s3-info.md)。

## 在传输过程中强制加密
<a name="UsingEncryptionInTransit.enforcement"></a>

在向 Amazon S3 传输数据时，执行传输中数据加密是一种最佳安全实践。您可以通过各种策略机制来实施仅限 HTTPS 的通信或使用特定的 TLS 版本。这些机制包括适用于 S3 存储桶的基于 IAM 资源的策略（[存储桶策略](bucket-policies.md)）、[服务控制策略](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html)（SCP）、[资源控制策略](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html)（RCP）和 [VPC 端点策略](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-access.html)。

### 用于强制实施传输中加密的存储桶策略示例
<a name="UsingEncryptionInTransit.bucket-policy-example"></a>

您可以使用 [S3 条件键](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazons3.html#amazons3-policy-keys) `s3:TlsVersion`，根据客户端使用的 TLS 版本限制对 Amazon S3 存储桶的访问权限。有关更多信息，请参阅 [示例 6：要求最低 TLS 版本](amazon-s3-policy-keys.md#example-object-tls-version)。

**Example 使用 `S3:TlsVersion` 条件键强制实施 TLS 1.3 的存储桶策略**  

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "DenyInsecureConnections",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::amzn-s3-demo-bucket1",
        "arn:aws:s3:::amzn-s3-demo-bucket1/*"
      ],
      "Condition": {
        "NumericLessThan": {
          "s3:TlsVersion": "1.3"
        }
      }
    }
  ]
}
```

您可以在 S3 存储桶策略中使用 `aws:SecureTransport` [全局条件键](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html)来检查请求是否通过 HTTPS（TLS）发送。与前一示例不同，此条件不检查是否使用了特定 TLS 版本。有关更多信息，请参阅 [仅限 HTTPS 请求访问](example-bucket-policies.md#example-bucket-policies-use-case-HTTP-HTTPS-1)。

**Example 使用 `aws:SecureTransport` 全局条件键强制实施 HTTPS 的存储桶策略**  

```
{
    "Version":"2012-10-17",		 	 	 		 	 	 
    "Statement": [
     {
        "Sid": "RestrictToTLSRequestsOnly",		 	 	 
        "Action": "s3:*",
        "Effect": "Deny",
        "Resource": [
            "arn:aws:s3:::amzn-s3-demo-bucket1",
            "arn:aws:s3:::amzn-s3-demo-bucket1/*"
        ],
        "Condition": {
            "Bool": {
                "aws:SecureTransport": "false"
            }
        },
        "Principal": "*"
    }
  ]
}
```

**基于这两种键的策略示例和更多示例**  
您可以在一个策略中使用前面示例中演示的两种条件键。有关更多信息和其他强制实施方法，请参阅 AWS Storage 博客文章 [Enforcing encryption in transit with TLS1.2 or higher with Amazon S3](https://aws.amazon.com/blogs/storage/enforcing-encryption-in-transit-with-tls1-2-or-higher-with-amazon-s3/)。

# 将混合后量子 TLS 与 Amazon S3 结合使用
<a name="UsingEncryptionInTransit.PQ-TLS"></a>

Amazon S3 支持 TLS 网络加密协议的混合后量子密钥交换选项。当您向采用 TLS 1.3 的 Amazon S3 端点发出请求时，可以使用此 TLS 选项。S3 支持用于 TLS 会话的传统密码套件，使得针对密钥交换机制进行的暴力攻击在现有技术下是不可行的。不过，如果与密码学相关的量子计算机在未来得到广泛应用，那么 TLS 密钥交换机制中使用的传统密码套件将会容易受到这些攻击。目前，业内已就混合后量子密钥交换达成共识，此方法将传统加密算法与后量子要素相结合，可确保 TLS 连接至少与传统密码套件一样强大。目前，Amazon S3 支持混合 PQ-TLS，符合行业标准的 IANA 规范。

如果您正在开发的应用程序高度重视通过 TLS 连接传输的数据的长期保密性，则应考虑在大规模量子计算机投入使用之前迁移到后量子密码术的计划。作为责任共担模型的一部分，S3 在我们的服务端点上启用了量子安全密码学技术。由于浏览器和应用程序支持 PQ-TLS，S3 将选择尽可能强的配置来保护传输中数据。

**支持的端点类型和 AWS 区域**

适用于 Amazon S3 的后量子 TLS 在所有 AWS 区域中提供。有关每个 AWS 区域中 S3 端点的列表，请参阅《Amazon Web Services 一般参考》**中的 [Amazon Simple Storage Service 端点和限额](https://docs.aws.amazon.com/general/latest/gr/s3.html)。

**注意**  
除了适用于 Amazon S3 的 AWS PrivateLink、多区域接入点和 S3 Vectors 之外，所有 S3 端点均支持混合后量子 TLS。

## 将混合后量子 TLS 与 Amazon S3 结合使用
<a name="pqtls-details"></a>

您必须配置客户端，使其向 Amazon S3 发出请求来支持混合后量子 TLS。在设置 HTTP 客户端测试环境或生产环境时，请注意以下信息：

**传输中加密**

混合后量子 TLS 仅适用于传输中加密。这可以在数据从客户端传输到 S3 端点的过程中保护数据。这种新支持的功能与 Amazon S3 服务器端加密（默认使用 AES-256 算法）相结合，为客户提供了传输中数据和静态数据的抗量子加密。有关 Amazon S3 中服务器端加密的更多信息，请参阅[使用服务器端加密保护数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html)。

**支持的客户端**

要使用混合后量子 TLS，您需要使用支持此功能的客户端。AWSSDK 和工具的加密功能及配置因语言和运行时而异。要了解有关特定工具的后量子密码术的更多信息，请参阅[启用混合后量子 TLS](https://docs.aws.amazon.com/payment-cryptography/latest/userguide/pqtls-details.html)。

**注意**  
对于向 Amazon S3 发出的请求，AWS CloudTrail 事件或 S3 服务器访问日志中不提供 PQ-TLS 密钥交换详细信息。

## 了解后量子 TLS 的更多信息
<a name="pqtls-see-also"></a>

有关使用混合后量子 TLS 的更多信息，请参阅以下资源。
+ 要了解 AWS 的后量子密码术，包括博客文章和研究论文的链接，请参阅 [Post-Quantum Cryptography for AWS](https://aws.amazon.com/security/post-quantum-cryptography/)。
+ 有关 s2n-tls 的信息，请参阅[推出新的开源 TLS 实施 s2n-tls](https://aws.amazon.com/blogs/security/introducing-s2n-a-new-open-source-tls-implementation/) 和[使用 s2n-tls](https://github.com/aws/s2n-tls/tree/main/docs/usage-guide)。
+ 有关 AWS 公共运行时 HTTP 客户端的信息，请参阅《AWS SDK for Java 2.x 开发者指南》中的 [配置基于 AWS CRT 的 HTTP 客户端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html)**。
+ 有关美国国家标准和技术研究所 (NIST) 开展的后量子密码加密技术项目的信息，请参阅[后量子密码加密技术](https://csrc.nist.gov/Projects/Post-Quantum-Cryptography)。
+ 有关 NIST 后量子密码术标准化的信息，请参阅 [NIST's Post-Quantum Cryptography Standardization](https://csrc.nist.gov/Projects/post-quantum-cryptography/post-quantum-cryptography-standardization)。

# 为客户端配置混合后量子 TLS
<a name="pqtls-how-to"></a>

要将 PQ-TLS 与 Amazon S3 结合使用，您需要将客户端配置为支持后量子密钥交换算法。您还要确保客户端支持混合方法，该方法将传统的椭圆曲线加密与后量子算法 [例如 ML-KEM（模块化格基密钥封装机制）] 相结合。

具体配置取决于客户端库和编程语言。有关多信息，请参阅[启用混合后量子 TLS](https://docs.aws.amazon.com/payment-cryptography/latest/userguide/pqtls-details.html)。

## 客户端配置示例：适用于 Java 2 的 AWS SDK
<a name="UsingEncryptionInTransit.PQ-TLS.configuration.java2-sdk"></a>

在此过程中，为 AWS 公共运行时 HTTP 客户端添加一个 Maven 依赖项。然后配置一个优先使用后量子 TLS 的 HTTP 客户端。然后，创建使用 HTTP 客户端的 Amazon S3 客户端。

**注意**  
AWS 公共运行时 HTTP 客户端现已开放预览版，并于 2023 年 2 月全面开放。在正式发行版中，`tlsCipherPreference` 类和 `tlsCipherPreference()` 方法参数已替换为 `postQuantumTlsEnabled()` 方法参数替。如果您在预览期间使用此示例，则需要更新您的代码。

1. 将 AWS 公共运行时客户端添加到您的 Maven 依赖项中。我们建议您使用最新可用版本。

   例如，以下语句将 AWS 公共运行时客户端的版本 `2.30.22` 添加到您的 Maven 依赖项中。

   ```
   <dependency>
       <groupId>software.amazon.awssdk</groupId>
       <artifactId>aws-crt-client</artifactId>
       <version>2.30.22</version>
   </dependency>
   ```

1. 要启用混合后量子密码套件，请将 AWS SDK for Java 2.x 添加到您的项目中并进行初始化。然后按照以下示例所示，在您的 HTTP 客户端上启用混合后量子密码套件。

   此代码使用 `postQuantumTlsEnabled()` 方法参数来配置 [AWS 通用运行时 HTTP 客户端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html)，从而优先使用推荐的混合后量子密码套件（即 ECDH 与 ML-KEM 的组合）。然后，它使用配置的 HTTP 客户端来构建一个 Amazon S3 异步客户端实例（即 ）[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html)。此代码完成后，`S3AsyncClient` 实例上的所有 [Amazon S3 API](https://docs.aws.amazon.com/AmazonS3/latest/API/) 请求都将使用混合后量子 TLS。
**重要**  
从 v2.35.11 开始，调用方不再需要设置 `.postQuantumTlsEnabled(true)` 来为客户端启用混合后量子 TLS。所有高于 v2.35.11 的版本都默认启用后量子 TLS。

   ```
   // Configure HTTP client
   SdkAsyncHttpClient awsCrtHttpClient = AwsCrtAsyncHttpClient.builder()
             .postQuantumTlsEnabled(true)
             .build();
   
   // Create the Amazon S3 async client
   S3AsyncClient s3Async = S3AsyncClient.builder()
            .httpClient(awsCrtHttpClient)
            .build();
   ```

1. 使用混合后量子 TLS 测试您的 Amazon S3 调用。

   在配置的 Amazon S3 客户端上调用 Amazon S3 API 操作时，系统会使用混合后量子 TLS 将您的调用传输到 Amazon S3 端点。要测试您的配置，您需要调用一个 Amazon S3 API，例如 `[ListBuckets](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html)`。

   ```
   ListBucketsResponse reponse = s3Async.listBuckets();
   ```

### 测试您的混合后量子 TLS 配置
<a name="pqtls-testing"></a>

请考虑在调用 Amazon S3 的应用程序上，使用混合密码套件运行下面的测试。
+ 运行负载测试和基准测试。混合密码套件的执行方式与传统密钥交换算法有所不同。您可能需要调整连接超时，以便增加握手时间。如果您在 AWS Lambda 函数内部运行，请增大执行超时设置。
+ 请尝试从不同位置进行连接。根据您的请求采用的网络路径，您可能会发现中间主机、代理或带有深度数据包检查 (DPI) 功能的防火墙阻止了请求。这可能是因为在 TLS 握手的 [ClientHello](https://tools.ietf.org/html/rfc5246#section-7.4.1.2) 部分中使用了新的密码套件，或者密钥交换消息比较大。如果您在解决这些问题时遇到麻烦，请与安全团队或 IT 管理员一起，更新相关配置并取消阻止新的 TLS 密码套件。

# 互联网络流量隐私
<a name="inter-network-traffic-privacy"></a>

此主题介绍 Amazon S3 如何保护从服务到其他位置的连接。

## 服务与本地客户端和应用之间的流量
<a name="inter-network-traffic-privacy-on-prem"></a>

以下连接可以和 AWS PrivateLink 合并使用，以提供私有联网和 AWS 之间的连接性：
+ 一个 AWS Site-to-Site VPN 连接。有关更多信息，请参阅[什么是 AWS Site-to-Site VPN？](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html)
+ 一个 Direct Connect 连接。有关更多信息，请参阅[什么是 Direct Connect？](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html)

通过网络访问 Amazon S3 是通过 AWS 发布的 API 进行的。客户端必须支持传输层安全性协议（TLS）1.2。我们建议将 TLS 1.3 用于混合后量子密钥交换。客户端还必须支持具有完全向前保密（PFS）的密码套件，例如 Ephemeral Diffie-Hellman（DHE）或 Elliptic Curve Diffie-Hellman Ephemeral（ECDHE）。大多数现代系统（如 Java 7 及更高版本）都支持这些模式。此外，必须使用与 IAM 主体关联的访问密钥 ID 和秘密访问密钥签名请求，或者可以使用 [AWS Security Token Service（STS）](https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html)生成临时安全证书来签名请求。

## 同一区域中 AWS 资源之间的流量
<a name="inter-network-traffic-privacy-within-region"></a>

Amazon S3 的 Virtual Private Cloud (VPC) 端点是 VPC 内的逻辑实体，仅允许连接到 Amazon S3。VPC 将请求路由到 Amazon S3 并将响应路由回 VPC。有关更多信息，请参阅 *VPC 用户指南*中的 [VPC 端点](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints.html)。有关您可用来从 VPC 端点控制 S3 存储桶访问的示例存储桶策略，请参阅[使用存储桶策略控制从 VPC 端点的访问](example-bucket-policies-vpc-endpoint.md)。

# AWS PrivateLink适用于 Amazon S3 的
<a name="privatelink-interface-endpoints"></a>

借助适用于 Amazon S3 的 AWS PrivateLink，您可以在 Virtual Private Cloud (VPC) 中预置*接口 VPC 端点*（接口端点）。这些端点可从本地（通过 VPN 及 Direct Connect）或其他 AWS 区域（通过 VPC 对等连接）中的应用程序直接访问。

接口端点由一个或多个弹性网络接口 (ENI) 代表，这些接口是从 VPC 中的子网分配的私有 IP 地址。通过接口端点向 Amazon S3 发出的请求仍留在 Amazon 网络上。您还可以通过 AWS Direct Connect 或 AWS Virtual Private Network (Site-to-Site VPN) 从本地部署应用程序访问 VPC 中的接口端点。有关如何将 VPC 与本地网络连接的更多信息，请参阅 [Direct Connect User Guide](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html) 和 [AWS Site-to-Site VPN User Guide](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html)。

有关接口端点的一般信息，请参阅 *AWS PrivateLink 指南*中的[接口 VPC 端点 (AWS PrivateLink)](https://docs.aws.amazon.com/vpc/latest/privatelink/vpce-interface.html)。

**Topics**
+ [适用于 Amazon S3 的 VPC 端点类型](#types-of-vpc-endpoints-for-s3)
+ [适用于 Amazon S3 的 AWS PrivateLink 的限制和局限性](#privatelink-limitations)
+ [创建 VPC 端点](#s3-creating-vpc)
+ [访问 Amazon S3 接口端点](#accessing-s3-interface-endpoints)
+ [VPC 端点的 IP 地址类型](#privatelink-ip-address-types)
+ [VPC 端点的 DNS 记录 IP 类型](#privatelink-dns-record-types)
+ [私有 DNS](#private-dns)
+ [从 S3 接口端点访问存储桶、接入点和 Amazon S3 控制 API 操作](#accessing-bucket-and-aps-from-interface-endpoints)
+ [更新本地 DNS 配置](#updating-on-premises-dns-config)
+ [为 Amazon S3 创建 VPC 端点策略](#creating-vpc-endpoint-policy)

## 适用于 Amazon S3 的 VPC 端点类型
<a name="types-of-vpc-endpoints-for-s3"></a>

您可以使用两种类型的 VPC 端点访问 Amazon S3：*网关端点*和*接口端点*（使用 AWS PrivateLink）。*网关端点*是您在路由表中指定的网关，用于通过 AWS 网络从 VPC 访问 Amazon S3。*接口端点*通过私有 IP 地址，使用 VPC 对等连接或 AWS Transit Gateway 将请求从您的 VPC 内、本地或其它 AWS 区域中的 VPC 路由到 Amazon S3，从而扩展网关端点的功能。有关更多信息，请参阅[什么是 VPC 对等连接?](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html)和 [Transit Gateway 与 VPC 对等连接](https://docs.aws.amazon.com/whitepapers/latest/building-scalable-secure-multi-vpc-network-infrastructure/transit-gateway-vs-vpc-peering.html)。

接口端点与网关端点兼容。如果您在 VPC 中有现有网关端点，则可以在同一 VPC 中使用这两种类型的端点。


|  适用于 Amazon S3 的网关端点  |  适用于 Amazon S3 的接口端点  | 
| --- | --- | 
|  在这两种情况下，您的网络流量仍保留在 AWS 网络中。  | 
|  使用 Amazon S3 公有 IP 地址  |  使用 VPC 中的私有 IP 地址访问 Amazon S3  | 
|  使用相同的 Simple Storage Service (Amazon S3) DNS 名称  |  [需要特定于端点的 Simple Storage Service (Amazon S3) DNS 名称](https://docs.aws.amazon.com/AmazonS3/latest/userguide/privatelink-interface-endpoints.html#accessing-s3-interface-endpoints)  | 
|  不允许从本地访问  |  允许从本地访问  | 
|  不允许从其他 AWS 区域访问  |  允许从另一个 AWS 区域使用 VPC 对等连接或 AWS Transit Gateway 进行访问  | 
|  不计费  |  已计费  | 

有关更多信息，请参阅《AWS PrivateLink 指南》**中的[网关端点](https://docs.aws.amazon.com/vpc/latest/privatelink/gateway-endpoints.html)和[接口 VPC 端点](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html)。

## 适用于 Amazon S3 的 AWS PrivateLink 的限制和局限性
<a name="privatelink-limitations"></a>

VPC 限制应用于适用于 Amazon S3 的 AWS PrivateLink。有关更多信息，请参阅《AWS PrivateLink 指南》**中的[接口端点注意事项](https://docs.aws.amazon.com/vpc/latest/privatelink/vpce-interface.html#vpce-interface-limitations)和 [AWS PrivateLink 限额](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-limits-endpoints.html)。此外，以下限制将适用：

Amazon S3 的接口端点不支持以下各项：
+ [美国联邦信息处理标准 (FIPS) 端点](https://aws.amazon.com/compliance/fips/)
+ [网站端点](WebsiteEndpoints.md)
+ [传统全局端点](VirtualHosting.md#deprecated-global-endpoint)
+ [S3 短划线区域端点](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html)
+ 在不同 AWS 区域中的桶之间使用 [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/API_UploadPartCopy.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html)
+ 传输层安全性协议（TLS）1.0
+ 传输层安全性协议（TLS）1.1
+ 传输层安全性协议（TLS）1.3
+ 混合后量子传输层安全性协议（TLS）

## 创建 VPC 端点
<a name="s3-creating-vpc"></a>

要创建 VPC 接口端点，请参阅《AWS PrivateLink Guide》**中的 [Create a VPC endpoint](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html#create-interface-endpoint-aws)。要创建 VPC 网关端点，请参阅《AWS PrivateLink 指南》**中的[创建 VPC 端点](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-s3.html#create-gateway-endpoint-s3)。

## 访问 Amazon S3 接口端点
<a name="accessing-s3-interface-endpoints"></a>

创建接口端点时，Amazon S3 会生成两种特定于端点的 S3 DNS 名称：*区域*和*地区*。
+ *区域* DNS 名称包括唯一的 VPC 端点 ID、服务标识符、AWS 区域和以其命名的 `vpce.amazonaws.com`。例如，对于 VPC 端点 ID `vpce-1a2b3c4d`，生成的 DNS 名称可能类似于 `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com`。
+ *区域* DNS 名称包括可用区 – 例如 `vpce-1a2b3c4d-5e6f-us-east-1a.s3.us-east-1.vpce.amazonaws.com`。如果您的架构隔离了可用区，则可以使用此选项。例如，您可以将其用于故障控制或降低区域数据传输成本。

可以从 S3 公有 DNS 域解析特定于端点的 S3 DNS 名称。

Amazon S3 的 VPC 端点支持不同类型的 IP 地址，包括：IPv4、IPv6 和双堆栈。请参阅[VPC 端点的 IP 地址类型](#privatelink-ip-address-types)和[VPC 端点的 DNS 记录 IP 类型](#privatelink-dns-record-types)。

## VPC 端点的 IP 地址类型
<a name="privatelink-ip-address-types"></a>

Amazon S3 的 VPC 端点支持不同类型的 IP 地址，包括：
+ **IPv4**

  VPC 端点可以配置为仅使用 IPv4 地址进行连接。
+ **IPv6**

  VPC 端点可以配置为仅使用 IPv6 地址进行连接。
+ **双堆栈**

  VPC 端点可以配置为双堆栈模式，同时支持 IPv4 和 IPv6 地址。这提供了通过 IPv4 或 IPv6 网络访问 Amazon S3 灵活性。

您为 VPC 端点选择的 IP 地址类型取决于应用程序和基础设施的联网要求。注意事项包括您的 VPC、本地网络以及在 Amazon S3 的互联网连接中使用的 IP 地址方案。有关更多信息，请参阅《Amazon Virtual Private Cloud 指南》**中[接口端点](https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-access-aws-services.html#aws-service-ip-address-type)和[网关端点](https://docs.aws.amazon.com/vpc/latest/privatelink/gateway-endpoints.html#gateway-endpoint-ip-address-type)的 IP 地址类型。

## VPC 端点的 DNS 记录 IP 类型
<a name="privatelink-dns-record-types"></a>

根据您的 IP 地址类型，在调用 VPC 端点时，AWS 服务可以返回 `A` 记录、`AAAA` 记录或 `A` 和 `AAAA` 记录。您可以通过修改 DNS 记录 IP 类型来自定义 AWS 服务返回的记录类型。下表显示支持的 DNS 记录 IP 类型和 IP 地址类型：


| 支持的 IP 地址类型 | DNS 记录 IP 类型 | 
| --- | --- | 
| IPv4 | IPv4 | 
| IPv6 | IPv6 | 
| 双堆栈 | 双堆栈、IPv4、IPv6、服务定义 | 

### 为 Amazon S3 配置服务定义的 DNS 记录 IP 类型
<a name="privatelink-dns-record-types-configure"></a>

如果您为 Amazon S3 创建网关端点，将 DNS 记录 IP 类型配置为服务定义并使用区域服务端点（例如 `s3.us-east-2.amazonaws.com`），则 Amazon S3 会向客户端返回 `A` 记录。相反，如果您创建网关端点，使用双栈服务端点（例如 `s3.dualstack.us-east-2.amazonaws.com`）并为 DNS 记录 IP 类型选择 `service-defined`，则 Amazon S3 会向客户端返回 `A` 和 `AAAA` 记录。

同样，如果您创建接口端点，启用私有 DNS 并为 DNS 记录类型选择服务定义，则对于区域服务端点（例如 `s3.us-east-2.amazonaws.com`），Amazon S3 会向客户端返回 `A` 记录。而对于双堆栈服务端点（例如 `s3.dualstack.us-east-2.amazonaws.com`），Amazon S3 会同时返回 `A` 和 `AAAA` 记录。有关更多信息，请参阅《VPC 用户指南》**中[接口端点](https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-access-aws-services.html#aws-services-dns-record-ip-type)和[网关端点](https://docs.aws.amazon.com/vpc/latest/privatelink/gateway-endpoints.html#gateway-endpoint-dns-record-ip-type)的 DNS 记录 IP 类型。

下表显示网关和接口端点支持的 DNS 记录 IP 类型：


| IP 地址类型 | S3 网关端点支持的 DNS 记录 IP 类型 | S3 接口端点支持的 DNS 记录 IP 类型  | 
| --- | --- | --- | 
| IPv4 | IPv4，服务定义\$1 | IPv4 | 
| IPv6 | IPv6，服务定义\$1 | IPv6 | 
| 双堆栈 | IPv4、IPv6、双堆栈、服务定义\$1 | 双堆栈\$1、IPv4、IPv6、服务定义 | 

\$1 表示默认 DNS 记录 IP 类型。

要在现有 S3 网关或接口端点上启用 IPv6 连接，请将端点的 IP 地址类型更新为 **Dualstack**。更新后，Amazon S3 会自动使用网关端点的 IPv6 地址更新路由表。然后，您可以使用双栈服务端点（例如 `s3.dualstack.us-east-2.amazonaws.com`），Amazon S3 将为双堆栈 S3 DNS 查询返回 `A` 和 `AAAA` 记录。如果您要将 IPv6 与区域服务端点（例如 `s3.us-east-2.amazonaws.com`）结合使用，请将端点的 IP 地址类型修改为 **Dualstack**；将 DNS 记录 IP 类型修改为 **Dualstack**。然后，Amazon S3 将为区域 S3 DNS 查询返回 `A` 和 `AAAA` 记录。

**注意事项**  
如果您的网关端点的 IP 地址类型默认配置为 `IPv4`，而 DNS 记录 IP 类型为 `service-defined`，则对于双栈服务端点（例如 `s3.dualstack.us-east-2.amazonaws.com`），使用 `AAAA` 记录的流量将不会通过网关端点路由。相反，如果存在与 IPv6 兼容的路径，则流量将通过该路径路由，否则就丢弃。例如，如果您的虚拟私有云（VPC）有互联网网关，则在这种情况下，IPv6 流量将通过 VPC 中的互联网网关路由。如果您想确保流量始终通过 VPC 端点路由，可以使用 Amazon S3 存储桶策略，该策略在未使用指定的 VPC 端点情况下限制对特定存储桶的访问权限。有关更多信息，请参阅[限制对特定 VPC 端点的访问](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies-vpc-endpoint.html#example-bucket-policies-restrict-accesss-vpc-endpoint)。
如果您的接口端点具有默认配置的 IP 地址类型（即 IPv4），并且 DNS 记录 IP 类型为 IPv4，则不支持双栈服务端点（例如 `ass3.dualstack.us-east-2.amazonaws.com`）。使用双堆栈服务端点 `A` 或 `AAAA` 记录的流量不会通过接口端点路由。相反，如果存在其他兼容的路径，则流量将通过该路径路由，否则就丢弃。
要创建或修改 DNS 记录 IP 类型并非服务定义的网关端点，需要将 `enableDnsSupport` 和 `enableDnsHostnames` VPC 属性都设置为 true。

## 私有 DNS
<a name="private-dns"></a>

VPC 接口端点的私有 DNS 选项简化了通过 VPC 端点路由 S3 流量的过程，并帮助您充分利用应用程序可用的最低成本网络路径。您可以使用私有 DNS 选项来路由区域 S3 流量，而无需更新 S3 客户端以使用接口端点的端点特定 DNS 名称，也无需管理 DNS 基础设施。启用私有 DNS 名称后，对于以下端点，区域 S3 DNS 查询将解析为 AWS PrivateLink 的私有 IP 地址：
+ 区域存储桶端点（例如 `s3.us-east-1.amazonaws.com`）
+ 控制端点（例如 `s3-control.us-east-1.amazonaws.com`）
+ 接入点端点（例如 `s3-accesspoint.us-east-1.amazonaws.com`）

如果您的 VPC 中有网关端点，则可以通过现有 S3 网关端点自动路由 VPC 内请求，并通过接口端点自动路由本地请求。此方法允许您使用 VPC 内流量不计费的网关端点来优化网络成本。您的本地应用程序可以在入站解析器端点的帮助下使用 AWS PrivateLink。Amazon 为您的 VPC 提供 DNS 服务器，称为 Route 53 Resolver。入站解析器端点将来自本地网络的 DNS 查询转发到 Route 53 Resolver。

**重要**  
要在使用**仅对入站端点启用私有 DNS** 时充分利用成本最低的网络路径，您的 VPC 中必须存在网关端点。当选择**仅对入站端点启用私有 DNS** 选项时，网关端点的存在有助于确保 VPC 内流量始终通过 AWS 私有网络路由。当选择**仅对入站端点启用私有 DNS** 选项时，必须维护此网关端点。如果要删除网关端点，则必须先清除**仅对入站端点启用私有 DNS**。  
如果您想要将现有接口端点更新为**仅对入站端点启用私有 DNS**，请先确认您的 VPC 具有 S3 网关端点。有关网关端点和管理私有 DNS 名称的更多信息，请分别参阅《AWS PrivateLink 指南》**中的[网关 VPC 端点](https://docs.aws.amazon.com//vpc/latest/privatelink/vpce-gateway.html)和[管理 DNS 名称](https://docs.aws.amazon.com//vpc/latest/privatelink/manage-dns-names.html)。  
启用**仅适用于入站解析器的私有 DNS** 时，网关端点的 `dnsRecordIpType` 必须与接口端点的该项匹配或者为**服务定义**。

**仅对入站端点启用私有 DNS** 选项仅适用于支持网关端点的服务。

有关创建使用**仅对入站端点启用私有 DNS** 的 VPC 端点的更多信息，请参阅《AWS PrivateLink 指南》**中的[创建接口端点](https://docs.aws.amazon.com//vpc/latest/privatelink/create-interface-endpoint.html)。

**使用 VPC 控制台**

在控制台中，您有两个选项：**启用 DNS 名称**和**仅对入站端点启用私有 DNS**。**启用 DNS 名称**是 AWS PrivateLink 支持的选项。通过使用**启用 DNS 名称**选项，您可以使用 Amazon 的与 Amazon S3 的私有连接，同时向默认公有端点 DNS 名称发出请求。启用此选项后，客户可以利用其应用程序可用的成本最低的网络路径。

当您在 Amazon S3 的现有或新的 VPC 接口端点上启用私有 DNS 名称时，默认情况下会选择**仅对入站端点启用私有 DNS** 选项。如果选择此选项，则您的应用程序仅对本地流量使用接口端点。这种 VPC 内流量会自动使用成本较低的网关端点。或者，您可以清除**仅对入站端点启用私有 DNS**，以通过您的接口端点路由所有 S3 请求。

**使用 AWS CLI**

如果不指定 `PrivateDnsOnlyForInboundResolverEndpoint` 的值，则它默认为 `true`。但是，在您的 VPC 应用设置之前，它会进行检查以确保 VPC 中存在网关端点。如果 VPC 中存在网关端点，则调用成功。否则，您将看到以下错误消息：

要将 PrivateDnsOnlyForInboundResolverEndpoint 设置为 true，VPC *vpce\$1id* 必须具有该服务的网关端点。

**对于新的接口 VPC 端点**

使用 `private-dns-enabled` 和 `dns-options` 属性通过命令行启用私有 DNS。`dns-options` 属性中的 `PrivateDnsOnlyForInboundResolverEndpoint` 选项必须设置为 `true`。将 `user input placeholders` 替换为您自己的信息。

```
aws ec2 create-vpc-endpoint \
--region us-east-1 \
--service-name s3-service-name \
--vpc-id client-vpc-id \
--subnet-ids client-subnet-id \ 
--vpc-endpoint-type Interface  \
--private-dns-enabled  \
--ip-address-type ip-address-type \ 
--dns-options PrivateDnsOnlyForInboundResolverEndpoint=true \
--security-group-ids client-sg-id
```

**对于现有 VPC 端点**

如果您想对现有 VPC 端点使用私有 DNS，请使用以下示例命令并将 `user input placeholders` 替换为您自己的信息。

```
aws ec2 modify-vpc-endpoint \
--region us-east-1 \
--vpc-endpoint-id client-vpc-id \
--private-dns-enabled \
--dns-options PrivateDnsOnlyForInboundResolverEndpoint=false
```

如果您想更新现有 VPC 端点以仅对入站解析器启用私有 DNS，请使用以下示例并将示例值替换为您自己的值。

```
aws ec2 modify-vpc-endpoint \
--region us-east-1 \
--vpc-endpoint-id client-vpc-id \
--private-dns-enabled \
--dns-options PrivateDnsOnlyForInboundResolverEndpoint=true
```

## 从 S3 接口端点访问存储桶、接入点和 Amazon S3 控制 API 操作
<a name="accessing-bucket-and-aps-from-interface-endpoints"></a>

您可以使用 AWS CLI 或 AWS SDK 通过 S3 接口端点访问存储桶、S3 接入点和 Amazon S3 控制 API 操作。

下图显示了 VPC 控制台**详细信息**选项卡，您可以在其中找到 VPC 端点的 DNS 名称。在此示例中，*VPC 端点 ID (vpce-id)* 为 `vpce-0e25b8cdd720f900e`，*DNS 名称*为 `*.vpce-0e25b8cdd720f900e-argc85vg.s3.us-east-1.vpce.amazonaws.com`。







![\[VPC 控制台中的详细信息选项卡。\]](http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/images/vpc-console-details-tab.png)


使用 DNS 名称访问资源时，将 *\$1* 替换为相应的值。用来代替 `*` 的相应值如下所示：
+ `bucket`
+ `accesspoint`
+ `control`

例如，要访问存储桶，请使用如下所示的 *DNS 名称*。

 `bucket.vpce-0e25b8cdd720f900e-argc85vg.s3.us-east-1.vpce.amazonaws.com`

有关如何使用 DNS 名称访问存储桶、接入点和 Amazon S3 控制 API 操作的示例，请参阅下面的章节：[AWS CLI 示例](#privatelink-aws-cli-examples)和[AWS SDK 示例](#privatelink-aws-sdk-examples)。

有关如何查看端点特定 DNS 名称的更多信息，请参阅《VPC 用户指南》**中的[查看端点服务私有 DNS 名称配置](https://docs.aws.amazon.com/vpc/latest/privatelink/view-vpc-endpoint-service-dns-name.html)。

### AWS CLI 示例
<a name="privatelink-aws-cli-examples"></a>

要在 AWS CLI 命令中通过 S3 接口端点访问 S3 存储桶、S3 接入点或 Amazon S3 控制 API操作，请使用 `--region` 和 `--endpoint-url` 参数。

**示例：使用端点 URL 列出存储桶中的对象**  
在以下示例中，将存储桶名称 `my-bucket`、区域 `us-east-1` 和 VPC 端点 ID 的 DNS 名称 `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。

```
aws s3 ls s3://my-bucket/ --region us-east-1 --endpoint-url https://bucket.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com
```

**示例：使用端点 URL 列出接入点中的对象**
+ **方法 1** – 将接入点的 Amazon 资源名称（ARN）与接入点端点结合使用

  将 ARN `us-east-1:123456789012:accesspoint/accesspointexamplename`、区域 `us-east-1` 和 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。

  ```
  aws s3api list-objects-v2 --bucket arn:aws:s3:us-east-1:123456789012:accesspoint/accesspointexamplename --region us-east-1 --endpoint-url https://accesspoint.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com
  ```

  如果您无法成功运行该命令，请将 AWS CLI 更新为最新版本，然后重试。有关更新说明的更多信息，请参阅《AWS Command Line Interface 用户指南》**中的[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com//cli/latest/userguide/getting-started-install.html#getting-started-install-instructions)。
+ **方法 2** – 将接入点的别名与区域存储桶端点结合使用

  在以下示例中，将接入点别名 `accesspointexamplename-8tyekmigicmhun8n9kwpfur39dnw4use1a-s3alias`、区域 `us-east-1` 和 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。

  ```
  aws s3api list-objects-v2 --bucket accesspointexamplename-8tyekmigicmhun8n9kwpfur39dnw4use1a-s3alias --region us-east-1 --endpoint-url https://bucket.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com
  ```
+ **方法 3** – 将接入点的别名与接入点端点结合使用

  首先，要构造一个包含存储桶作为主机名一部分的 S3 端点，请将寻址样式设置为 `virtual` 以供 `aws s3api` 使用。有关 `AWS configure` 的更多信息，请参阅《AWS Command Line Interface 用户指南》**中的[配置和凭证文件设置](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)。

  ```
  aws configure set default.s3.addressing_style virtual
  ```

  然后，在以下示例中，将接入点别名 `accesspointexamplename-8tyekmigicmhun8n9kwpfur39dnw4use1a-s3alias`、区域 `us-east-1` 和 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。有关接入点别名的更多信息，请参阅[接入点别名](access-points-naming.md#access-points-alias)

  ```
  aws s3api list-objects-v2 --bucket accesspointexamplename-8tyekmigicmhun8n9kwpfur39dnw4use1a-s3alias --region us-east-1 --endpoint-url https://accesspoint.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com
  ```

**示例：使用端点 URL 通过 S3 控制 API 操作列出任务**  
在以下示例中，将区域 `us-east-1`、VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 和账户 ID `12345678` 替换为您自己的信息。

```
aws s3control --region us-east-1 --endpoint-url https://control.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com list-jobs --account-id 12345678
```

### AWS SDK 示例
<a name="privatelink-aws-sdk-examples"></a>

要在使用 AWS SDK 时通过 S3 接口端点访问 S3 存储桶、S3 接入点、Amazon S3 控制 API 操作，请将 SDK 更新到最新版本。然后，将客户端配置为使用端点 URL 通过 S3 接口端点访问存储桶、接入点或 Amazon S3 控制 API 操作。

------
#### [ SDK for Python (Boto3) ]

**示例：使用端点 URL 访问 S3 存储桶**  
在以下示例中，将区域 `us-east-1` 和 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。

```
s3_client = session.client(
service_name='s3',
region_name='us-east-1',
endpoint_url='https://bucket.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com'
)
```

**示例：使用端点 URL 访问 S3 接入点**  
在以下示例中，将区域 `us-east-1` 和 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。

```
ap_client = session.client(
service_name='s3',
region_name='us-east-1',
endpoint_url='https://accesspoint.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com'
)
```

**示例：使用端点 URL 访问 Amazon S3 控制 API**  
在以下示例中，将区域 `us-east-1` 和 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。

```
control_client = session.client(
service_name='s3control',
region_name='us-east-1',
endpoint_url='https://control.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com'
)
```

------
#### [ SDK for Java 1.x ]

**示例：使用端点 URL 访问 S3 存储桶**  
在以下示例中，将 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。

```
// bucket client
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withEndpointConfiguration(
        new AwsClientBuilder.EndpointConfiguration(
                "https://bucket.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com",
                Regions.DEFAULT_REGION.getName()
        )
).build();
List<Bucket> buckets = s3.listBuckets();
```

**示例：使用端点 URL 访问 S3 接入点**  
在以下示例中，将 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 和 ARN `us-east-1:123456789012:accesspoint/prod` 替换为您自己的信息。

```
// accesspoint client
final AmazonS3 s3accesspoint = AmazonS3ClientBuilder.standard().withEndpointConfiguration(
        new AwsClientBuilder.EndpointConfiguration(
                "https://accesspoint.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com",
                Regions.DEFAULT_REGION.getName()
        )
).build();
ObjectListing objects = s3accesspoint.listObjects("arn:aws:s3:us-east-1:123456789012:accesspoint/prod");
```

**示例：使用端点 URL 访问 Amazon S3 控制 API 操作**  
在以下示例中，将 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 替换为您自己的信息。

```
// control client
final AWSS3Control s3control = AWSS3ControlClient.builder().withEndpointConfiguration(
        new AwsClientBuilder.EndpointConfiguration(
                "https://control.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com",
                Regions.DEFAULT_REGION.getName()
        )
).build();
final ListJobsResult jobs = s3control.listJobs(new ListJobsRequest());
```

------
#### [ SDK for Java 2.x ]

**示例：使用端点 URL 访问 S3 存储桶**  
在以下示例中，将 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 和区域 `Region.US_EAST_1` 替换为您自己的信息。

```
// bucket client
Region region = Region.US_EAST_1;
s3Client = S3Client.builder().region(region)
                   .endpointOverride(URI.create("https://bucket.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com"))
                   .build()
```

**示例：使用端点 URL 访问 S3 接入点**  
在以下示例中，将 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 和区域 `Region.US_EAST_1` 替换为您自己的信息。

```
// accesspoint client
Region region = Region.US_EAST_1;
s3Client = S3Client.builder().region(region)
                   .endpointOverride(URI.create("https://accesspoint.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com"))
                   .build()
```

**示例：使用端点 URL 访问 Amazon S3 控制 API**  
在以下示例中，将 VPC 端点 ID `vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com` 和区域 `Region.US_EAST_1` 替换为您自己的信息。

```
// control client
Region region = Region.US_EAST_1;
s3ControlClient = S3ControlClient.builder().region(region)
                                 .endpointOverride(URI.create("https://control.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com"))
                                 .build()
```

------

## 更新本地 DNS 配置
<a name="updating-on-premises-dns-config"></a>

使用特定于端点的 DNS 名称访问适用于 Amazon S3 的接口端点时，您无需更新本地 DNS 解析程序。您可以使用来自公有 Amazon S3 DNS 域的接口端点的私有 IP 地址解析特定于端点的 DNS 名称。

### 使用接口端点访问 Amazon S3，无需 VPC 中的网关端点和互联网网关
<a name="using-interface-endpoints"></a>

VPC 中的接口端点可以通过 Amazon 网络将 VPC 内的应用程序和本地应用程序路由到 Amazon S3，如下图所示。

![\[数据流程图，显示了使用接口端点和 AWS PrivateLink 访问 Amazon S3。\]](http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/images/interface-endpoints.png)


该图阐释了以下内容：
+ 您的本地部署网络使用 Direct Connect 或者 Site-to-Site VPN 连接到 VPC A。
+ 本地和 VPC A 中的应用程序使用特定于端点的 DNS 名称通过 S3 接口端点访问 Amazon S3。
+ 本地部署应用程序通过 Direct Connect（或 Site-to-Site VPN）将数据发送到 VPC 中的接口端点。AWS PrivateLink 通过 AWS 网络将数据从接口端点移动到 Amazon S3。
+ VPC 中的应用程序还向接口端点发送通信。AWS PrivateLink 通过 AWS 网络将数据从接口端点移动到 Amazon S3。

### 在同一 VPC 中同时使用网关端点和接口端点来访问 Amazon S3
<a name="using-gateway-and-interface-endpoints"></a>

您可以创建接口端点并将现有网关端点保留在同一 VPC 中，如下图所示。通过这种方法，您可以允许 VPC 内应用程序继续通过网关端点访问 Amazon S3，而无需付费。然后，只有您的本地应用程序才会使用接口端点访问 Amazon S3。要通过这种方式访问 Amazon S3，您必须更新本地应用程序，以使用适用于 Amazon S3 的特定于端点的 DNS 名称。

![\[数据流程图，显示了使用网关端点和接口端点访问 Amazon S3。\]](http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/images/interface-and-gateway-endpoints.png)


下图说明了以下内容：
+ 本地部署应用程序使用特定于端点的 DNS 名称通过 Direct Connect（或 Site-to-Site VPN）将数据发送到 VPC 中的接口端点。AWS PrivateLink 通过 AWS 网络将数据从接口端点移动到 Amazon S3。
+ 使用默认的区域 Amazon S3 名称，VPC 内应用程序会将数据发送到通过 AWS 网络连接到 Amazon S3 的网关端点。

有关网关端点的更多信息，请参阅 *VPC 用户指南*中的[网关 VPC 端点](https://docs.aws.amazon.com/vpc/latest/privatelink/vpce-gateway.html)。

## 为 Amazon S3 创建 VPC 端点策略
<a name="creating-vpc-endpoint-policy"></a>

您可以为 VPC 端点附加控制对 Amazon S3 的访问的端点策略。该策略指定以下信息：
+ 可执行操作的 AWS Identity and Access Management (IAM) 主体 
+ 可执行的操作 
+ 可对其执行操作的资源 

您还可以使用 Amazon S3 存储桶策略，通过使用存储桶策略中的 `aws:sourceVpce` 条件限制从特定 VPC 端点访问特定存储桶。以下示例显示了限制对存储桶或端点的访问的策略。

**Topics**
+ [示例：限制从 VPC 端点对特定存储桶的访问](#privatelink-example-restrict-access-to-bucket)
+ [示例：限制从 VPC 端点对特定账户中存储桶的访问](#privatelink-example-access-bucket-in-specific-account-only)
+ [示例：限制对 S3 存储桶策略中特定 VPC 端点的访问](#privatelink-example-restrict-access-to-vpc-endpoint)

### 示例：限制从 VPC 端点对特定存储桶的访问
<a name="privatelink-example-restrict-access-to-bucket"></a>

您可以创建一个端点策略来仅允许访问特定的 Amazon S3 存储桶。如果您的 VPC 中有使用存储桶的其他 AWS 服务，这种策略会非常有用。以下存储桶策略限制为仅可访问 `amzn-s3-demo-bucket1`。要使用此端点策略，请将 `amzn-s3-demo-bucket1` 替换为您的存储桶名称。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "Policy1415115909151",
  "Statement": [
    { "Sid": "Access-to-specific-bucket-only",
      "Principal": "*",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket1",
                   "arn:aws:s3:::amzn-s3-demo-bucket1/*"]
    }
  ]
}
```

------

### 示例：限制从 VPC 端点对特定账户中存储桶的访问
<a name="privatelink-example-access-bucket-in-specific-account-only"></a>

您可以创建一个端点策略，以限制仅访问特定 AWS 账户中的 S3 存储桶。要防止 VPC 内的客户端访问并非您拥有的存储桶，请在端点策略中使用以下语句。以下示例语句创建了一个策略，此策略将访问限制为由单个 AWS 账户 ID *`111122223333`* 拥有的资源。

```
{
  "Statement": [
    {
      "Sid": "Access-to-bucket-in-specific-account-only",
      "Principal": "*",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Deny",
      "Resource": "arn:aws:s3:::*",
      "Condition": {
        "StringNotEquals": {
          "aws:ResourceAccount": "111122223333"
        }
      }
    }
  ]
}
```

**注意**  
要指定要访问的资源的 AWS 账户 ID，可以在 IAM 策略中使用 `aws:ResourceAccount` 或 `s3:ResourceAccount` 键。但请注意，有些 AWS 服务依赖于访问 AWS 托管式存储桶。因此，在 IAM 策略中使用 `aws:ResourceAccount` 或 `s3:ResourceAccount` 键也可能会影响对这些资源的访问。

### 示例：限制对 S3 存储桶策略中特定 VPC 端点的访问
<a name="privatelink-example-restrict-access-to-vpc-endpoint"></a>

以下 Amazon S3 存储桶策略仅允许从 VPC 端点 `vpce-1a2b3c4d` 访问特定的存储桶 `amzn-s3-demo-bucket2`。如果未使用指定的端点，则该策略拒绝对存储桶的所有访问。`aws:sourceVpce` 条件指定端点，而不需要 VPC 端点资源的 Amazon 资源名称（ARN），只需要端点 ID。要使用此存储桶策略，请将 `amzn-s3-demo-bucket2` 和 `vpce-1a2b3c4d` 替换为您的存储桶名称和端点。

**重要**  
当应用以下 Amazon S3 存储桶策略来限制仅可访问特定的 VPC 端点时，您可能会无意中屏蔽对存储桶的访问。存储桶策略旨在专门限制存储桶访问源自 VPC 端点的连接，而这可能会屏蔽到存储桶的所有连接。有关如何修复此问题的信息，请参阅[我的存储桶策略有错误的 VPC 或 VPC 端点 ID。*支持 知识中心*内的如何修复策略才能访问存储桶？](https://aws.amazon.com/premiumsupport/knowledge-center/s3-regain-access/)。
在使用以下示例策略之前，将 VPC 端点 ID 替换为适合您的使用案例的值。否则，您将无法访问您的存储桶。
此策略禁用*控制台*访问指定的存储桶，因为控制台请求不是来自指定的 VPC 端点。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "Policy1415115909152",
  "Statement": [
    { "Sid": "Access-to-specific-VPCE-only",
      "Principal": "*",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket2",
                   "arn:aws:s3:::amzn-s3-demo-bucket2/*"],
      "Condition": {"StringNotEquals": {"aws:sourceVpce": "vpce-1a2b3c4d"}}
    }
  ]
}
```

------

有关更多策略示例，请参阅 *VPC 用户指南*中的 [Amazon S3 端点](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-s3.html#vpc-endpoints-policies-s3)。

有关 VPC 连接的更多信息，请参阅 AWS 白皮书 [Amazon Virtual Private Cloud 连接性选项](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/welcome.html)中的 [Network-to-VPC connectivity options](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/network-to-amazon-vpc-connectivity-options.html)（从网络到 VPC 的连接性选项）。

# Amazon S3 的合规性验证
<a name="s3-compliance"></a>

作为多个 AWS 合规性计划的一部分，第三方审计员将评估 Amazon S3 的安全性和合规性，包括以下内容：
+ 系统和组织控制 (SOC)
+ 支付卡行业数据安全标准（PCI DSS）
+ 联邦风险与授权管理项目（FedRAMP）
+ 健康保险流通与责任法案（HIPAA）

AWS 在[合规性计划范围内的 AWS 服务](https://aws.amazon.com/compliance/services-in-scope/)中提供特定合规性计划范围内经常更新的 AWS 服务列表。

第三方审计报告可供您使用 AWS Artifact 进行下载。有关更多信息，请参阅[下载 AWS Artifact 中的报告](https://docs.aws.amazon.com/artifact/latest/ug/downloading-documents.html)。

有关 AWS 合规性计划的更多信息，请参阅 [AWS 合规性计划](https://aws.amazon.com/compliance/programs/)。

您在使用 Amazon S3 时的合规性责任由您数据的敏感性、您组织的合规性目标以及适用的法律法规决定。如果您对 Amazon S3 的使用需遵守 HIPAA、PCI 或 FedRAMP 等标准，AWS 提供了以下实用资源：
+ [安全性和合规性快速入门指南](https://aws.amazon.com/quickstart/?awsf.quickstart-homepage-filter=categories%23security-identity-compliance)，介绍了架构注意事项，以及在 AWS 上部署侧重于安全性和合规性的基准环境的步骤。
+ [设计符合 HIPAA 安全性和合规性要求的架构](https://docs.aws.amazon.com/whitepapers/latest/architecting-hipaa-security-and-compliance-on-aws/architecting-hipaa-security-and-compliance-on-aws.html)概述了公司如何使用 AWS 来帮助自己满足 HIPAA 要求。
+ [AWS 合规性资源](https://aws.amazon.com/compliance/resources/)提供了可能适用于您的行业和位置的多个不同业务手册和指南。
+ [AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config.html) 可用于评估您的资源配置对内部实践、行业指南和法规的遵循情况。
+ [AWS Security Hub](https://docs.aws.amazon.com/securityhub/latest/userguide/what-is-securityhub.html) 提供了 AWS 中安全状态的全面视图，可帮助您检查是否符合安全行业标准和最佳实践。
+ [使用对象锁定以锁定对象](object-lock.md) 可以帮助您满足金融服务监管机构（如SEC、FINRA 和 CFTC）的技术要求，这些监管机构对于某些类型的账簿和记录信息要求编写一次、多次读取 (WORM) 数据存储。
+ [使用 S3 清单对数据进行编目和分析](storage-inventory.md) 可帮助您出于业务、合规性和法规要求，使用它来审核和报告对象的复制和加密状态。

# Amazon S3 中的恢复能力
<a name="disaster-recovery-resiliency"></a>

AWS 全球基础设施围绕区域和可用区构建。AWS 区域提供多个在物理上独立且隔离的可用区，这些可用区通过延迟低、吞吐量高且冗余性高的网络连接在一起。这些可用区为您提供了高效的方法来设计和操作应用程序和数据库。与传统的单个数据中心基础设施或多个数据中心基础设施相比，它们具有更高的可用性、容错性和可扩展性。如果您尤其需要跨更长地理距离复制您的数据，您可以使用[在区域内和跨区域复制对象](replication.md)，它允许跨不同 AWS 区域中的存储桶自动异步复制对象。

每个 AWS 区域都有多个可用区。您可以跨一个区域中的多个可用区部署您的应用来获得容错性和低延迟。可用区通过快速、私密的光纤网络来互相连接，使您能够轻松构建可在可用区之间无中断地自动实现故障转移的应用程序。

有关 AWS 区域 和可用区的更多信息，请参阅 [AWS 全球基础设施](https://aws.amazon.com/about-aws/global-infrastructure/)。

除了 AWS 全球基础设施之外，Amazon S3 还提供多种特征，以帮助支持您的数据恢复能力和备份需求。

**生命周期配置**  
生命周期配置是一组规则，用于定义 Amazon S3 对一组对象应用的操作。利用生命周期配置规则，您可以指示 Amazon S3 将对象转换为较低成本的存储类，或者归档或删除它们。有关更多信息，请参阅 [管理对象的生命周期](object-lifecycle-mgmt.md)。

**版本控制**  
版本控制是在相同的存储桶中保留对象的多个变量的方法。对于 Amazon S3 存储桶中存储的每个对象，您可以使用版本控制功能来保存、检索和还原它们的各个版本。使用版本控制能够轻松从用户意外操作和应用程序故障中恢复数据。有关更多信息，请参阅 [使用 S3 版本控制保留对象的多个版本](Versioning.md)。

**S3 对象锁定**  
您可以使用 S3 对象锁定通过*一次写入、多次读取* (WORM) 模式存储对象。​使用 S3 对象锁定时，您可以在固定的时间段内或无限期地阻止删除或覆盖对象。S3 对象锁定让您可以满足需要 WORM 存储的法规要求，或只是添加一个额外的保护层来防止对象被更改和删除。有关更多信息，请参阅 [使用对象锁定以锁定对象](object-lock.md)。

**存储类**  
Amazon S3 提供一系列存储类，可供选择，具体取决于您的工作负载要求。S3 Standard-IA 和 S3 One Zone-IA 存储类用于大约每月访问一次且需要毫秒访问的数据。S3 Glacier Instant Retrieval 存储类专为长期归档数据而设计，您可以访问几毫秒的访问权限，大约每季度访问一次。对于不需要立即访问的归档数据，例如备份，您可以使用 S3 Glacier Flexible Retrieval 或 S3 Glacier Deep Archive 存储类。有关更多信息，请参阅 [了解和管理 Amazon S3 存储类](storage-class-intro.md)。

下面的安全最佳实践也处理弹性：
+ [Enable versioning](security-best-practices.md#versioning)
+ [Consider Amazon S3 cross-region replication](security-best-practices.md#cross-region)
+ [Identify and audit all your Amazon S3 buckets](security-best-practices.md#audit)

## Amazon S3 备份的加密
<a name="backup-encryption"></a>

如果您使用 Amazon S3 存储备份，则备份的加密取决于这些存储桶的配置。Amazon S3 提供了一种方法来设置 S3 存储桶的默认加密行为。您可以对存储桶设置默认加密，以便在存储桶中存储所有对象时对这些对象进行加密。默认加密支持存储在 AWS KMS 中的密钥（SSE-KMS）。有关更多信息，请参阅 [为 Amazon S3 存储桶设置默认服务器端加密行为](bucket-encryption.md)。

有关版本控制和对象锁定的详细信息，请参阅以下主题：[使用 S3 版本控制保留对象的多个版本](Versioning.md) [使用对象锁定以锁定对象](object-lock.md)

# Amazon S3 中的基础设施安全性
<a name="network-isolation"></a>

作为一个受管理的服务，Amazon S3 受到 AWS 全局网络安全过程的保护，这些过程在 [AWS Well-Architected 框架](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/welcome.html)的安全支柱中进行了描述。

通过网络访问 Amazon S3 是通过 AWS 发布的 API 进行的。客户端必须支持传输层安全性协议（TLS）1.2。此外，我们建议支持 TLS 1.3 和混合后量子密钥交换。要了解 AWS 的后量子密码术，包括博客文章和研究论文的链接，请参阅 [Post-Quantum Cryptography for AWS](https://aws.amazon.com/security/post-quantum-cryptography/)。

**注意**  
除了适用于 Amazon S3 的 AWS PrivateLink 和多区域接入点之外，所有 S3 端点均支持 TLS 1.3。

客户端还必须支持具有完全向前保密 (PFS) 的密码套件，例如 Ephemeral Diffie-Hellman (DHE) 或 Elliptic Curve Diffie-Hellman Ephemeral (ECDHE)。另外，请求必须使用 AWS 签名 V4 或 AWS 签名 V2 进行签名，同时要求提供有效凭证。

这些 API 可以从任何网络位置调用。然而，Amazon S3 的确支持基于资源的访问策略，其中可以包含基于源 IP 地址的限制。您还可以使用 Amazon S3 存储桶策略控制从特定 Virtual Private Cloud（VPC）端点或特定 VPC 对存储桶的访问。事实上，这隔离了在 AWS 网络中仅从特定 VPC 到给定 Amazon S3 存储桶的网络访问。有关更多信息，请参阅 [使用存储桶策略控制从 VPC 端点的访问](example-bucket-policies-vpc-endpoint.md)。

下面的安全最佳实践也处理 Amazon S3 中的基础设施安全性：
+ [Consider VPC endpoints for Amazon S3 access](security-best-practices.md#end-points)
+ [Identify and audit all your Amazon S3 buckets](security-best-practices.md#audit)

# Amazon S3 中的配置和漏洞分析
<a name="vulnerability-analysis-and-management"></a>

AWS 负责处理基本安全任务，如来宾操作系统（OS）和数据库补丁、防火墙配置和灾难恢复等。这些流程已通过相应第三方审核和认证。有关更多详细信息，请参阅以下资源：
+ [Amazon S3 的合规性验证](s3-compliance.md)
+ [责任共担模式](https://aws.amazon.com/compliance/shared-responsibility-model/)
+ [Amazon Web Services：安全过程概述](https://d0.awsstatic.com/whitepapers/Security/AWS_Security_Whitepaper.pdf)

以下安全最佳实践还处理 Amazon S3 中的配置和漏洞分析：
+ [Identify and audit all your Amazon S3 buckets](security-best-practices.md#audit)
+ [Enable AWS Config（启用 Gem）](security-best-practices.md#config)

# 访问权限管理
<a name="security-access-management"></a>

Amazon S3 提供了各种访问管理工具。以下是这些功能和工具的列表。您并不需要所有这些访问管理工具，但必须使用一个或多个工具来授予对 Amazon S3 存储桶、对象和其它 [S3 资源](access-management.md#access-management-resources)的访问权限。正确应用这些工具有助于确保只有目标用户才能访问您的资源。

最常用的访问管理工具是*访问策略*。访问策略可以是附加到 AWS 资源的*基于资源的策略*，例如存储桶的存储桶策略。访问策略也可以是附加到 AWS Identity and Access Management（IAM）身份（如 IAM 用户、组或角色）的*基于身份的策略*。访问策略描述了谁可以访问哪些内容。编写访问策略来向 AWS 账户和 IAM 用户、组和角色授予对资源执行操作的权限。例如，您可以向另一个 AWS 账户授予 `PUT Object` 权限，以使该账户可以向您的存储桶上传对象。

以下是 Amazon S3 中提供的访问管理工具。有关 Amazon S3 访问控制的更全面指南，请参阅 [Amazon S3 中的访问控制](access-management.md)。

**存储桶策略**  
Amazon S3 存储桶策略是采用 JSON 格式的 [AWS Identity and Access Management（IAM）基于资源的策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)，该策略附加到特定的存储桶。使用存储桶策略来向其它 AWS 账户或 IAM 身份授予对相应存储桶及其中对象的权限。使用存储桶策略可以满足许多 S3 访问管理使用案例的要求。通过存储桶策略，您可以对存储桶访问权限进行个性化设置，以协助确保只有您已批准的身份才能访问资源并在其中执行操作。有关更多信息，请参阅 [Amazon S3 的存储桶策略](bucket-policies.md)。

**基于身份的策略**  
基于身份的策略或 IAM 用户策略是一种 [AWS Identity and Access Management（IAM）策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)。基于身份的策略是采用 JSON 格式的策略，该策略附加到您的 AWS 账户中的 IAM 用户、组或角色。您可以使用基于身份的策略，来向 IAM 身份授予对您的存储桶或对象的访问权限。您可以在您的账户中创建 IAM 用户、组和角色，并为其附加访问策略。然后，您可以授予对 AWS 资源（包括 Amazon S3 资源）的访问权限。有关更多信息，请参阅 [Amazon S3 基于身份的策略](security_iam_id-based-policy-examples.md)。

**S3 访问权限管控**  
使用 S3 Access Grants 为企业身份目录（例如 Active Directory）中的身份以及 AWS Identity and Access Management（IAM）身份创建对您的 Amazon S3 数据的访问授权。S3 Access Grants 可协助您大规模管理数据权限。此外，S3 Access Grants 还会记录最终用户身份以及用于访问 AWS CloudTrail 中 S3 数据的应用程序。这提供了详细的审计历史记录，细至与 S3 存储桶中数据的所有访问权限对应的最终用户身份。有关更多信息，请参阅 [使用 S3 Access Grants 管理访问权限](access-grants.md)。

**接入点**  
对于使用 S3 上的共享数据集的应用程序，Amazon S3 接入点可简化大规模管理数据访问的事宜。接入点是附加到存储桶的命名网络端点。您可以使用接入点来大规模执行 S3 对象操作，例如上传和检索对象。一个存储桶最多可附加 10000 个接入点，对于每个接入点，您可以强制实施不同的权限和网络控制，从而让您可以详细控制对于 S3 对象的访问权限。S3 接入点可以与同一个账户或其它可信账户中的存储桶相关联。接入点策略是与底层存储桶策略一起进行评估的基于资源的策略。有关更多信息，请参阅 [通过接入点管理对共享数据集的访问](access-points.md)。

**访问控制列表 (ACL)**  
ACL 是用于确定被授权者和所授予权限的授权列表。ACL 向其它 AWS 账户授予基本的读取或写入权限。ACL 使用特定于 Amazon S3 的 XML 架构。ACL 是一种 [AWS Identity and Access Management（IAM）策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)。对象 ACL 用于管理对于对象的访问权限，而存储桶 ACL 用于管理对存储桶的访问权限。使用存储桶策略，整个存储桶只有单个策略，但可以为每个对象指定对象 ACL。我们建议您将 ACL 保持为关闭状态，除非有必须单独控制每个对象的访问权限的情况。有关 ACL 的更多信息，请参阅 [为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。

**警告**  
Amazon S3 中的大多数现代使用案例不需要使用 ACL。

**对象所有权**  
要管理对于对象的访问权限，您必须是该对象的拥有者。您可以使用对象所有权存储桶级别设置，来控制上传到存储桶的对象的所有权。此外，使用对象所有权来开启 ACL。默认情况下，对象所有权设为*强制存储桶拥有者设置*，并且所有 ACL 均处于关闭状态。关闭 ACL 后，存储桶拥有者拥有存储桶中的所有对象，并独占管理对数据的访问权限。为了管理访问权限，存储桶拥有者使用策略或其它访问管理工具（ACL 除外）。有关更多信息，请参阅 [为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。

有关 Amazon S3 访问控制的更全面指南和其它最佳实践，请参阅 [Amazon S3 中的访问控制](access-management.md)。

# Amazon Simple Storage Service 数据清单
<a name="s3-data-inventory"></a>

## Amazon S3
<a name="s3-intro"></a>

Amazon S3 在 AWS 云中提供可扩展的对象存储。该服务支持您在 Web 上的任何位置存储和检索任意数量的数据。基于其独特的架构，S3 设计为可超过 99.999999999%（11 个 9）的数据持久性。此外，默认情况下，S3 将数据以冗余方式存储在至少 3 个可用区中，从而提供针对广泛灾难的内置弹性。客户可以将数据存储在单个可用区中以最大限度地降低存储成本或延迟，也可以存储在多个可用区中以获得弹性来抵御整个数据中心的永久性丢失，还可以存储在多个 AWS 区域中以满足地理弹性要求。主要特征

地理位置  
Amazon S3 托管在全球多个位置。您可以为数据选择靠近客户的存放位置。

桶  
存储桶是 Amazon S3 中用于存储对象的容器。每个对象都包含在一个存储桶中。

对象  
对象是 Amazon S3 中存储的基础实体。对象由对象数据和元数据组成。

存储类  
Amazon S3 提供针对不同使用案例进行优化的不同存储类别。

存储管理  
Amazon S3 具有存储管理功能，您可以使用这些功能来管理成本并遵守合规性要求。

访问管理和安全性  
Amazon S3 提供了用于审核和管理对存储桶和对象的访问的功能。

## 地理位置
<a name="s3-geographic-location"></a>

Amazon S3 在全球每个 AWS 区域中都可用。每个区域都是一个单独的地理区域。

### 这点为何如此重要
<a name="s3-geographic-location-why"></a>

在您确定要将数据存储在何处之后，您可以根据需要，决定是在相同位置还是不同位置部署功能等效的存储。

### 获取所有区域的 Amazon S3 存储桶总览
<a name="s3-geographic-location-how"></a>

使用以下 AWS CLI 命令：

```
   aws s3api list-buckets /
    --max-items 100 / 
    --page-size 100
```

有关更多信息，请参阅《AWS CLI Command Reference》中的 [list-buckets](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-buckets.html)。

## 桶
<a name="s3-buckets"></a>

Amazon S3 存储桶是对象的容器。每个存储桶在整个 AWS 中有一个唯一的名称。Amazon S3 支持四种类型的存储桶：通用存储桶、目录存储桶、表存储桶和向量存储桶。每种类型的存储桶都为不同的应用场景提供了一组独特的功能。有关不同存储桶类型的更多信息，请参阅《Amazon S3 用户指南》中的[存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html#BasicsBucket)。

### 为什么这些很重要
<a name="s3-buckets-why"></a>

列出存储桶后，可以通过查看各种存储桶配置设置来验证功能等效的存储系统的存储桶设置。

### 列出存储桶配置
<a name="s3-buckets-how"></a>

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

有关更多信息，请参阅《 AWS CLI Command Reference》中的 [get-bucket-versioning](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-bucket-versioning.html)。

## 对象
<a name="s3-objects"></a>

对象是 Amazon S3 中存储的基础实体。每个对象都由数据、键（名称）和元数据组成。

### 为什么这些很重要
<a name="s3-objects-why"></a>

了解对象特征有助于在功能等效的系统中规划等效的存储容量和性能要求。

### 列出对象及其属性
<a name="s3-objects-how"></a>

```
aws s3api list-objects-v2 --bucket amzn-s3-demo-bucket1 /
    --query 'Contents[].{Key: Key, Size: Size, LastModified: LastModified}'
```

有关更多信息，请参阅《AWS CLI Command Reference》中的 [list-objects-v2](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-objects-v2.html)。

## 存储类
<a name="s3-storage-classes"></a>
+ Amazon S3 Standard
+ Amazon S3 Intelligent-Tiering
+ Amazon S3 Standard-IA
+ Amazon S3 One Zone-IA
+ Amazon S3 Glacier Instant Retrieval
+ Amazon S3 Glacier Flexible Retrieval
+ Amazon S3 Glacier Deep Archive
+ Amazon S3 Express One Zone 存储类

### 为什么这些很重要
<a name="s3-storage-classes-why"></a>

了解存储类别使用情况有助于在功能等效的系统中确定适当的存储层。有关更多信息，请参阅《Amazon S3 用户指南》中的[了解和管理 Amazon S3 存储类别](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html)。

### 查看存储类别选择和使用情况
<a name="s3-storage-classes-how"></a>

您可以使用 Amazon S3 Storage Lens 存储统计管理工具来查看存储类别选择和使用情况。有关更多信息，请参阅《Amazon S3 用户指南》中的[了解和管理 Amazon S3 存储类别](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html)。

## 存储管理
<a name="s3-storage-management"></a>

### 这点为何如此重要
<a name="s3-storage-management-why"></a>

了解存储管理使用情况有助于规划等效的功能，以便在功能等效的系统中管理成本并遵守合规性要求。

### 查看存储管理功能选择和使用情况
<a name="s3-storage-management-how"></a>

可以使用 Amazon S3 Storage Lens 存储统计管理工具来查看存储管理功能的使用情况。有关更多信息，请参阅《Amazon S3 用户指南》中的 [Amazon S3 Storage Lens 存储统计管理工具指标词汇表](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage_lens_metrics_glossary.html)。

## 访问管理和安全性
<a name="s3-access-management"></a>

### 为什么这些很重要
<a name="s3-access-management-why"></a>

了解访问管理和安全设置有助于您规划等效的功能，以管理功能等效的系统中的访问和安全要求。

### 查看访问管理和安全设置
<a name="s3-access-management-how"></a>

列出存储桶后，可以通过查看各种存储桶配置设置来验证功能等效的存储系统的存储桶安全和访问设置。

```
aws s3api get-public-access-block --bucket amzn-s3-demo-bucket1 
aws s3api get-bucket-acl --bucket amzn-s3-demo-bucket1 
aws s3api get-bucket-encryption --bucket amzn-s3-demo-bucket1
aws s3api get-bucket-policy --bucket amzn-s3-demo-bucket1
```

## 数据传输
<a name="s3-data-transfer"></a>

可以使用多种方法从 Amazon S3 传输数据：
+ AWS CLI
+ AWS SDK
+ Amazon S3 REST API
+ 第三方工具

### 使用 AWS CLI 的示例
<a name="s3-data-transfer-examples"></a>

要下载整个存储桶：

```
aws s3 sync s3://amzn-s3-demo-bucket1 /local/path
```

有关更多信息，请参阅《AWS CLI Command Reference》中的 [sync](https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html)。

要下载特定对象：

```
aws s3 cp s3://amzn-s3-demo-bucket1/path/to/object /local/path
```

有关更多信息，请参阅《AWS CLI Command Reference》中的 [cp](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html)。

## 相关资源
<a name="s3-related-resources"></a>

以下是 Amazon S3 的其它特征：
+ [Amazon S3 中的访问控制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-management.html)
+ [Amazon S3 中的安全性](https://docs.aws.amazon.com/AmazonS3/latest/userguide/security.html)
+ [Amazon S3 中的数据保护](https://docs.aws.amazon.com/AmazonS3/latest/userguide/data-protection.html)
+ [Amazon S3 中的日志记录和监控](https://docs.aws.amazon.com/AmazonS3/latest/userguide/monitoring-overview.html)