使用 Amazon KMS (SSE-KMS) 指定服务器端加密 - Amazon Simple Storage Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 Amazon KMS (SSE-KMS) 指定服务器端加密

重要

Amazon S3 现在将具有 Amazon S3 托管密钥的服务器端加密(SSE-S3)作为 Amazon S3 中每个存储桶的基本加密级别。从 2023 年 1 月 5 日起,上传到 Amazon S3 的所有新对象都将自动加密,不会产生额外费用,也不会影响性能。S3 存储桶默认加密配置和上传的新对象的自动加密状态可在 Amazon CloudTrail 日志、S3 清单、S3 Storage Lens 存储统计管理工具、Amazon S3 控制台中获得,并可用作 Amazon Command Line Interface 和 Amazon SDK 中的附加 Amazon S3 API 响应标头。有关更多信息,请参阅默认加密常见问题解答

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

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

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

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

注意

您可以在 Amazon S3 中使用多区域 Amazon KMS keys。但是,Amazon S3 目前将多区域密钥视为单区域密钥,且不使用密钥的多区域特征。有关更多信息,请参阅 Amazon Key Management Service 开发人员指南中的使用多区域密钥

注意

如果您希望使用其他账户拥有的 KMS 密钥,则您必须有权使用该密钥。有关 KMS 密钥的跨账户权限的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的创建其他账户可以使用的 KMS 密钥

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

注意

如果更改对象的加密,则会创建一个新对象来替换旧对象。如果启用 S3 版本控制,则会创建对象的新版本,而现有对象将变为旧版本。更改属性的角色也会成为新对象(或对象版本)的拥有者。

添加或更改对象的加密
  1. 登录到 Amazon Web Services Management Console,然后通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/

  2. 在左侧导航窗格中,选择存储桶

  3. Bucket(存储桶) 列表中,请选择包含对象的存储桶的名称。

  4. Objects(对象) 列表中,请选择要为其添加或更改加密的对象的名称。

    将显示对象的详细信息页面,其中有几个部分显示您的对象的属性。

  5. 选择属性选项卡。

  6. 向下滚动到服务器端加密设置部分,然后选择编辑

    Edit server-side encryption (编辑服务器端加密) 页面随即打开。

  7. 服务器端加密下,对于加密设置,选择覆盖默认的加密存储桶设置

  8. 加密类型下,选择具有 Amazon Key Management Service 密钥的服务器端加密(SSE-KMS)

    重要

    如果您将 SSE-KMS 选项用于默认加密配置,则您将受到 Amazon KMS 的每秒请求数(RPS)限额限制。有关 Amazon KMS 限额以及如何请求增加限额的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的限额

  9. Amazon KMS 密钥下,执行以下操作以选择您的 KMS 密钥:

    • 要从可用的 KMS 密钥列表中进行选择,请选择从您的 Amazon KMS keys 中进行选择,然后从可用密钥的列表中选择您的 KMS 密钥

      Amazon 托管式密钥(aws/s3)和您的客户自主管理型密钥都显示在此列表中。有关客户自主管理型密钥的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的客户密钥和 Amazon 密钥

    • 要输入 KMS 密钥 ARN,请选择输入 Amazon KMS key ARN,然后在显示的字段中输入您的 KMS 密钥 ARN。

    • 要在 Amazon KMS 控制台中创建新的客户自主管理型密钥,请选择创建 KMS 密钥

      有关创建 Amazon KMS key 的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的创建密钥

    重要

    您只能使用与存储桶所在相同的 Amazon Web Services 区域中可用的 KMS 密钥。Amazon S3 控制台仅列出与存储桶位于同一区域中的前 100 个 KMS 密钥。要使用未列出的 KMS 密钥,您必须输入 KMS 密钥 ARN。如果您希望使用其他账户拥有的 KMS 密钥,则必须首先有权使用该密钥,然后必须输入相应的 KMS 密钥 ARN。

    Amazon S3 仅支持对称加密 KMS 密钥,不支持非对称 KMS 密钥。有关更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的确定对称和非对称 KMS 密钥

  10. 选择 Save Changes(保存更改)。

注意

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

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

如果您指定值为 aws:kmsx-amz-server-side-encryption 标头,则还可以使用以下请求标头:

  • x-amz-server-side-encryption-aws-kms-key-id

  • x-amz-server-side-encryption-context

  • x-amz-server-side-encryption-bucket-key-enabled

支持 SSE-KMS 的 Amazon S3 REST API 操作

以下 REST API 操作接受 x-amz-server-side-encryptionx-amz-server-side-encryption-aws-kms-key-idx-amz-server-side-encryption-context 请求标头。

  • PutObject – 使用 PUT API 操作上传数据时,您可以指定这些请求标头。

  • CopyObject – 在复制对象时,您同时具有源对象和目标对象。如果使用 CopyObject 操作传递 SSE-KMS 标头,它们仅应用于目标对象。复制现有对象时,不论源对象是否已经加密,都不会加密目标对象,除非您显式请求服务器端加密。

  • POST 对象 – 使用 POST 操作上传对象时,可在表单字段(而不是在请求标头)中提供相同的信息。

  • CreateMultipartUpload – 使用分段上传 API 操作上传大型对象时,可以指定这些标头。可以在启动分段上传请求中指定这些标头。

使用服务器端加密存储对象时,以下 REST API 操作的响应标头将返回 x-amz-server-side-encryption 标头。

重要
  • 如果您不让使用安全套接字层(SSL)、传输层安全性协议(TLS)或签名版本 4 发出针对受 Amazon KMS 保护的对象的所有 GETPUT 请求,则这些请求都将失败。

  • 如果对象使用 SSE-KMS,则不应对 GET 请求和 HEAD 请求发送加密请求标头,否则将显示 HTTP 400 BadRequest 错误。

加密上下文(x-amz-server-side-encryption-context)

如果您指定 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 中加密上下文的信息,请参阅 加密上下文。有关加密上下文的一般信息,请参阅 Amazon Key Management Service 开发人员指南中的 Amazon Key Management Service 概念 - 加密上下文

Amazon KMS 密钥 ID (x-amz-server-side-encryption-aws-kms-key-id)

您可以使用 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 将使用 Amazon 托管式密钥(aws/s3)来保护数据。如果要使用客户托管密钥,则必须提供客户托管密钥的 x-amz-server-side-encryption-aws-kms-key-id 标头。

重要

在 Amazon S3 中使用 Amazon KMS key 进行服务器端加密时,您必须选择对称加密 KMS 密钥。Amazon S3 仅支持对称加密 KMS 密钥。有关这些密钥的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的对称加密 KMS 密钥

S3 存储桶密钥(x-amz-server-side-encryption-aws-bucket-key-enabled)

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

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

当您上载新对象或复制现有对象时,可以指定使用具有 Amazon KMS 密钥的服务器端加密来加密数据。为此,请将 --server-side-encryption aws:kms 标头添加到请求。使用 --ssekms-key-id example-key-id 添加您创建的客户托管式 Amazon KMS 密钥。如果您指定 --server-side-encryption aws:kms 但未提供 Amazon KMS 密钥 ID,则 Amazon S3 将使用 Amazon 托管式密钥。

aws s3api put-object --bucket DOC-EXAMPLE-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 到 Amazon KMS 的请求流量来降低您的 Amazon KMS 请求成本。有关更多信息,请参阅使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本

aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key example-object-key --server-side-encryption aws:kms --bucket-key-enabled --body filepath

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

aws s3api copy-object --bucket DOC-EXAMPLE-BUCKET --key example-object-key --body filepath --bucket DOC-EXAMPLE-BUCKET --key example-object-key --sse aws:kms --sse-kms-key-id example-key-id --body filepath

使用 Amazon SDK 时,您可以请求 Amazon S3 使用 Amazon KMS keys 进行服务器端加密。此部分提供的示例演示了如何使用适用于 Java 和 .NET 的 Amazon SDK。有关其他 SDK 的信息,请转到示例代码和库

重要

在 Amazon S3 中使用 Amazon KMS key 进行服务器端加密时,您必须选择对称加密 KMS 密钥。Amazon S3 仅支持对称加密 KMS 密钥。有关这些密钥的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的对称加密 KMS 密钥

复制操作

在复制对象时,您添加相同的请求属性(ServerSideEncryptionMethodServerSideEncryptionKeyManagementServiceKeyId)来请求 Amazon S3 使用 Amazon KMS key。有关复制对象的更多信息,请参阅 复制对象

PUT 操作

Java

当使用 Amazon SDK for Java 上传对象时,您可以通过添加 SSEAwsKeyManagementParams 属性来请求 Amazon S3 使用 Amazon KMS key,如以下请求所示。

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

在这种情况下,Amazon S3 使用 Amazon 托管式密钥(aws/s3)(请参阅使用具有 Amazon KMS 密钥的服务器端加密(SSE-KMS))。您可以选择创建对称加密 KMS 密钥并在请求中指定该密钥。

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

有关创建客户托管密钥的更多信息,请参阅 Amazon Key Management Service 开发人员指南中的对 Amazon KMS API 进行编程

有关上传对象的工作代码示例,请参阅以下主题。要使用这些示例,您必须更新这些代码示例并提供加密信息,如上述代码片段所示。

.NET

当使用 Amazon SDK for .NET 上传对象时,您可以通过添加 ServerSideEncryptionMethod 属性来请求 Amazon S3 使用 Amazon KMS key,如以下请求所示。

PutObjectRequest putRequest = new PutObjectRequest { BucketName = DOC-EXAMPLE-BUCKET, Key = keyName, // other properties. ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS };

在这种情况下,Amazon S3 使用 Amazon 托管式密钥。有关更多信息,请参阅使用具有 Amazon KMS 密钥的服务器端加密(SSE-KMS)。您可以选择创建自己的对称加密客户托管式密钥并在请求中指定该密钥。

PutObjectRequest putRequest1 = new PutObjectRequest { BucketName = DOC-EXAMPLE-BUCKET, Key = keyName, // other properties. ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS, ServerSideEncryptionKeyManagementServiceKeyId = keyId };

有关创建客户托管密钥的更多信息,请参阅 Amazon Key Management Service 开发人员指南中的对 Amazon KMS API 进行编程

有关上传对象的工作代码示例,请参阅以下主题。要使用这些示例,您必须更新这些代码示例并提供加密信息,如上述代码片段所示。

预签名 URL

Java

在为使用 Amazon KMS key 加密的对象创建预签名 URL 时,您必须显式指定签名版本 4。

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

有关代码示例,请参阅 使用预签名 URL 共享对象

.NET

在为使用 Amazon KMS key 加密的对象创建预签名 URL 时,您必须显式指定签名版本 4。

AWSConfigs.S3Config.UseSignatureVersion4 = true;

有关代码示例,请参阅 使用预签名 URL 共享对象