

# 设置和监控目录存储桶的默认加密
<a name="s3-express-bucket-encryption"></a>

默认设置情况下，Amazon S3 存储桶启用了存储桶加密，并且通过具有 Amazon S3 托管密钥的服务器端加密（SSE-S3）来自动加密新对象。这种加密适用于您的 Amazon S3 存储桶中的所有新对象，并且不收取任何费用。

如果您需要对加密密钥进行更多控制，例如管理密钥轮换和访问策略授予，则可以选择使用具有 Amazon Key Management Service（Amazon KMS）密钥的服务器端加密（SSE-KMS）。

**注意**  
我们建议存储桶的默认加密使用所需的加密配置，并且不要在 `CreateSession` 请求或 `PUT` 对象请求中覆盖存储桶默认加密。然后，使用所需的加密设置自动对新对象进行加密。有关目录存储桶中加密覆盖行为的更多信息，请参阅 [Specifying server-side encryption with Amazon KMS for new object uploads](https://docs.amazonaws.cn/AmazonS3/latest/userguide/s3-express-specifying-kms-encryption.html)。
要使用 SSE-KMS 加密目录存储桶中的新对象，必须将具有 KMS 密钥（特别是客户自主管理型密钥）的 SSE-KMS 指定为目录存储桶的默认加密配置。然后，在为可用区端点 API 操作创建会话时，将在会话期间使用 SSE-KMS 和 S3 存储桶密钥自动加密和解密新对象。
当您将默认存储桶加密设置为 SSE-KMS 时，将始终为目录存储桶中的 `GET` 和 `PUT` 操作启用 S3 存储桶密钥，并且不能禁用。当您通过 [https://docs.amazonaws.cn/AmazonS3/latest/API/API_CopyObject.html](https://docs.amazonaws.cn/AmazonS3/latest/API/API_CopyObject.html)、[https://docs.amazonaws.cn/AmazonS3/latest/API/API_UploadPartCopy.html](https://docs.amazonaws.cn/AmazonS3/latest/API/API_UploadPartCopy.html)、[批量操作中的 Copy 操作](directory-buckets-objects-Batch-Ops.md)或 [import 任务](create-import-job.md)，将 SSE-KMS 加密的对象从通用存储桶复制到目录存储桶、从目录存储桶复制到通用存储桶，或在目录存储桶之间复制时，不支持 S3 存储桶密钥。在这种情况下，每次对 KMS 加密的对象发出复制请求时，Amazon S3 都会调用 Amazon KMS。有关 S3 存储桶密钥如何降低 Amazon KMS 请求成本的更多信息，请参阅[使用 Amazon S3 存储桶密钥降低 SSE-KMS 的成本](bucket-key.md)。
当您在目录存储桶中指定用于加密的 [Amazon KMS customer managed key](https://docs.amazonaws.cn/kms/latest/developerguide/concepts.html#customer-cmk) 时，请仅使用密钥 ID 或密钥 ARN。不支持 KMS 密钥的密钥别名格式。
对于目录存储桶中的默认加密，不支持具有 Amazon KMS 密钥的双层服务器端加密（DSSE-KMS）和具有客户提供的密钥的服务器端加密（SSE-C）。

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

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

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

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

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

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

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

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

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

1. 在**服务器端加密设置**下，目录存储桶使用具有 **Amazon S3 托管式密钥（SSE-S3）**的服务器端加密。

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

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

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

有关默认加密的更多信息，请参阅[为 Amazon S3 存储桶设置默认服务器端加密行为](bucket-encryption.md)。有关使用 Amazon 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 bucket-base-name--zone-id--x-s3 --server-side-encryption-configuration '{
    "Rules": [
        {
            "ApplyServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
            }
        }
    ]
}'
```

**Example – 使用 S3 存储桶密钥通过 SSE-KMS 进行默认加密**  
此示例使用 S3 存储桶密钥通过 SSE-KMS 配置默认存储桶加密。要使用该命令，请将*用户输入占位符* 替换为您自己的信息。  

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

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

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

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

## 使用 Amazon SDK
<a name="s3-express-kms-put-bucket-encryption-using-sdks"></a>

使用 Amazon SDK 时，您可以请求 Amazon S3 使用 Amazon KMS keys 进行服务器端加密。以下适用于 Java 和 .NET 的 Amazon SDK 示例使用 SSE-KMS 和 S3 存储桶密钥为目录存储桶配置默认加密配置。有关其它 SDK 的信息，请参阅 Amazon 开发人员中心上的[示例代码和库](https://www.amazonaws.cn/code)。

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

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

使用Amazon SDK for Java 2.x，可以通过 `applyServerSideEncryptionByDefault` 方法来指定目录存储桶的默认加密配置（也即使用 SSE-KMS 进行数据加密），从而请求 Amazon S3 使用 Amazon KMS key。可以创建对称加密 KMS 密钥并在请求中指定该密钥。

```
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutBucketEncryptionRequest;
import software.amazon.awssdk.services.s3.model.ServerSideEncryption;
import software.amazon.awssdk.services.s3.model.ServerSideEncryptionByDefault;
import software.amazon.awssdk.services.s3.model.ServerSideEncryptionConfiguration;
import software.amazon.awssdk.services.s3.model.ServerSideEncryptionRule;

public class Main {
    public static void main(String[] args) {
        S3Client s3 = S3Client.create();
        String bucketName = "bucket-base-name--zoneid--x-s3";
        String kmsKeyId = "your-kms-customer-managed-key-id";

        // AWS managed KMS keys aren't supported. Only customer-managed keys are supported.
        ServerSideEncryptionByDefault serverSideEncryptionByDefault = ServerSideEncryptionByDefault.builder()
                .sseAlgorithm(ServerSideEncryption.AWS_KMS)
                .kmsMasterKeyID(kmsKeyId)
                .build();

        // The bucketKeyEnabled field is enforced to be true.
        ServerSideEncryptionRule rule = ServerSideEncryptionRule.builder()
                .bucketKeyEnabled(true)
                .applyServerSideEncryptionByDefault(serverSideEncryptionByDefault)
                .build();
  
        ServerSideEncryptionConfiguration serverSideEncryptionConfiguration = ServerSideEncryptionConfiguration.builder()
                .rules(rule)
                .build();

        PutBucketEncryptionRequest putRequest = PutBucketEncryptionRequest.builder()
                .bucket(bucketName)
                .serverSideEncryptionConfiguration(serverSideEncryptionConfiguration)
                .build();

        s3.putBucketEncryption(putRequest);
        
    }
}
```

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

有关上传对象的工作代码示例，请参阅以下主题。要使用这些示例，您必须更新这些代码示例并提供加密信息，如上述代码片段所示。
+ 有关在单个操作中上传对象，请参阅 [将对象上传到目录存储桶](directory-buckets-objects-upload.md)。
+ 有关分段上传 API 操作，请参阅[对目录桶使用分段上传](s3-express-using-multipart-upload.md)。

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

使用适用于 .NET 的 Amazon SDK，可以通过 `ServerSideEncryptionByDefault` 属性来指定目录存储桶的默认加密配置（也即使用 SSE-KMS 进行数据加密），从而请求 Amazon S3 使用 Amazon KMS key。可以创建对称加密客户自主管理型密钥并在请求中指定该密钥。

```
    // Set the bucket server side encryption to use AWSKMS with a customer-managed key id.
    // bucketName: Name of the directory bucket. "bucket-base-name--zonsid--x-s3"
    // kmsKeyId: The Id of the customer managed KMS Key. "your-kms-customer-managed-key-id"
    // Returns True if successful.
    public static async Task<bool> SetBucketServerSideEncryption(string bucketName, string kmsKeyId)
    {
        var serverSideEncryptionByDefault = new ServerSideEncryptionConfiguration
        {
            ServerSideEncryptionRules = new List<ServerSideEncryptionRule>
            {
                new ServerSideEncryptionRule
                {
                    ServerSideEncryptionByDefault = new ServerSideEncryptionByDefault
                    {
                        ServerSideEncryptionAlgorithm = ServerSideEncryptionMethod.AWSKMS,
                        ServerSideEncryptionKeyManagementServiceKeyId = kmsKeyId
                    }
                }
            }
        };
        try
        {
            var encryptionResponse =await _s3Client.PutBucketEncryptionAsync(new PutBucketEncryptionRequest
            {
                BucketName = bucketName,
                ServerSideEncryptionConfiguration = serverSideEncryptionByDefault,
            });
            
            return encryptionResponse.HttpStatusCode == HttpStatusCode.OK;
        }
        catch (AmazonS3Exception ex)
        {
            Console.WriteLine(ex.ErrorCode == "AccessDenied"
                ? $"This account does not have permission to set encryption on {bucketName}, please try again."
                : $"Unable to set bucket encryption for bucket {bucketName}, {ex.Message}");
        }
        return false;
    }
```

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

有关上传对象的工作代码示例，请参阅以下主题。要使用这些示例，您必须更新这些代码示例并提供加密信息，如上述代码片段所示。
+ 有关在单个操作中上传对象，请参阅 [将对象上传到目录存储桶](directory-buckets-objects-upload.md)。
+ 有关分段上传 API 操作，请参阅[对目录桶使用分段上传](s3-express-using-multipart-upload.md)。

------

## 使用 Amazon CloudTrail 监控目录存储桶的默认加密
<a name="s3-express-bucket-encryption-tracking"></a>

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

**注意**  
目录存储桶不支持 EventBridge。
目录存储桶不支持具有 Amazon Key Management Service（Amazon KMS）密钥的双层服务器端加密（DSSE-KMS），也不支持具有客户提供的加密密钥的服务器端加密（SSE-C）。

有关使用 Amazon CloudTrail 监控默认加密的更多信息，请参阅[使用 Amazon CloudTrail 和 Amazon EventBridge 监控默认加密](bucket-encryption-tracking.md)。