

 适用于 Java 的 AWS SDK 1.x于2025年 end-of-support 12月31日达到。我们建议您迁移到 [AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html) 以继续获得新功能、可用性改进和安全更新。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon S3 加密客户端迁移
<a name="s3-encryption-migration"></a>

本主题介绍如何将应用程序从 () 加密客户端的版本 1 (V1) 迁移到版本 2 Amazon Simple Storage Service (Amazon S3 V2)，并确保应用程序在整个迁移过程中的可用性。

## 先决条件
<a name="s3-cse-prereq"></a>

 Amazon S3 客户端加密需要以下内容：
+ 应用程序环境中安装了 Java 8 或更高版本。 适用于 Java 的 AWS SDK [它可与 [Oracle Java SE 开发套件](https://www.oracle.com/java/technologies/javase-downloads.html)以及[红帽](https://developers.redhat.com/products/openjdk) OpenJDK 和 JDK [Amazon Corretto](https://aws.amazon.com/corretto/)等开放 Java 开发套件 (OpenJDK) 的发行版配合使用。AdoptOpen](https://adoptopenjdk.net/)
+ [Bouncy Castle 加密套餐](https://www.bouncycastle.org/download/bouncy-castle-java/)。你可以将 Bouncy Castle .jar 文件放在应用程序环境的类路径上，也可以在 Maven `pom.xml` 文件中添加 artifactId `bcprov-ext-jdk15on`（groupId 为 `org.bouncycastle`）的依赖项。

## 迁移概述
<a name="s3-cse-overview"></a>

此迁移分为两个阶段：

1.  **更新现有客户端以读取新格式。**将您的应用程序更新为使用 1.11.837 或更高版本， 适用于 Java 的 AWS SDK 然后重新部署该应用程序。这使应用程序中的 Amazon S3 客户端加密服务客户端能够解密由 V2 服务客户端创建的对象。如果您的应用程序使用多个 SDK AWS SDKs，则必须分别更新每个 SDK。

1.  **将加密和解密客户端迁移到 V2。**在所有 V1 加密客户端都能读取 V2 加密格式后，请更新应用程序代码中的 Amazon S3 客户端加密和解密客户端，以使用其 V2 等效格式。

## 更新现有客户端以读取新格式
<a name="s3-cse-update-project"></a>

V2 加密客户端使用旧版本 适用于 Java 的 AWS SDK 不支持的加密算法。

迁移的第一步是更新您的 V1 加密客户端，使其使用版本 1.11.837 或更高版本的 适用于 Java 的 AWS SDK。（建议您更新到最新发行版本，您可以在 [Java API Reference version 1.x](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc) 中找到该版本。） 为此，请更新项目配置中的依赖项。更新项目配置后，重新构建项目并重新部署。

完成这些步骤后，应用程序的 V1 加密客户端将能够读取 V2 加密客户端写入的对象。

### 更新项目配置中的依赖项
<a name="update-the-dependency-in-your-project-configuration"></a>

修改项目配置文件（例如 pom.xml 或 build.gradle）以使用版本 1.11.837 或更高版本的 适用于 Java 的 AWS SDK。然后重新构建项目并重新部署。

在部署新的应用程序代码之前完成此步骤，有助于确保整个实例集在迁移过程中的加密和解密操作保持一致。

#### 使用 Maven 的 示例
<a name="example-using-maven"></a>

pom.xml 文件中的代码段：

```
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk-bom</artifactId>
      <version>1.11.837</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
```

#### 使用 Gradle 的示例
<a name="example-using-gradle"></a>

build.gradle 文件中的代码段：

```
dependencies {
  implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.837')
  implementation 'com.amazonaws:aws-java-sdk-s3'
}
```

## 将加密和解密客户端迁移到 V2
<a name="s3-cse-update-code"></a>

使用最新的 SDK 版本更新项目后，您可以修改应用程序代码以使用 V2 客户端。为此，请先更新您的代码以使用新的服务客户端生成器。然后在该生成器上使用已重命名的方法提供加密材料，并根据需要进一步配置您的服务客户端。

这些代码片段演示了如何使用客户端加密 适用于 Java 的 AWS SDK，并提供了 V1 和 V2 加密客户端之间的比较。

 **V1** 

```
// minimal configuration in V1; default CryptoMode.EncryptionOnly.
EncryptionMaterialsProvider encryptionMaterialsProvider = ...
AmazonS3Encryption encryptionClient = AmazonS3EncryptionClient.encryptionBuilder()
             .withEncryptionMaterials(encryptionMaterialsProvider)
             .build();
```

 **V2** 

```
// minimal configuration in V2; default CryptoMode.StrictAuthenticatedEncryption.
EncryptionMaterialsProvider encryptionMaterialsProvider = ...
AmazonS3EncryptionV2 encryptionClient = AmazonS3EncryptionClientV2.encryptionBuilder()
             .withEncryptionMaterialsProvider(encryptionMaterialsProvider)
             .withCryptoConfiguration(new CryptoConfigurationV2()
                           // The following setting allows the client to read V1 encrypted objects
                           .withCryptoMode(CryptoMode.AuthenticatedEncryption)
             )
             .build();
```

上面的示例将 `cryptoMode` 设置为 `AuthenticatedEncryption`。此设置允许 V2 加密客户端读取 V1 加密客户端写入的对象。如果您的客户端不需要读取 V1 客户端写入的对象的功能，建议改用默认设置 `StrictAuthenticatedEncryption`。

### 构建 V2 加密客户端
<a name="construct-a-v2-encryption-client"></a>

V2 加密客户端可以通过调用 *AmazonS3 EncryptionClient v2.* EncryptionBuilder () 来构建。

您可以将所有现有的 V1 加密客户端替换为 V2 加密客户端。只要您通过将 V2 加密客户端配置为使用 `来允许 V2 加密客户端写入的任何对象，V2 加密客户端将始终能够读取 V1 加密客户端写入的任何对象。AuthenticatedEncryption ``cryptoMode`

创建新的 V2 加密客户端与创建 V1 加密客户端的方式非常相似。但还是有几个区别：
+ 您将使用 `CryptoConfigurationV2` 对象而不是 `CryptoConfiguration` 对象来配置客户端。此参数为必需参数。
+ V2 加密客户端的默认 `cryptoMode` 设置是 `StrictAuthenticatedEncryption`。对于 V1 加密客户端，该默认设置是 `EncryptionOnly`。
+ 加密客户端生成器上的方法 *withEncryptionMaterials()* 已重命名为 Prov *withEncryptionMaterialsider ()*。这只是一个表面更改，可以更准确地反映参数类型。配置服务客户端时必须使用新方法。

**注意**  
使用 AES-GCM 解密时，在开始使用解密的数据之前，请通读整个对象。这是为了验证自加密以来是否未对对象进行过修改。

### 使用加密材料提供程序
<a name="use-encryption-materials-providers"></a>

您可以继续使用与 V1 加密客户端相同的加密材料提供程序和加密材料对象。这些类负责提供加密客户端用来保护数据的密钥。它们可以在 V2 和 V1 加密客户端中互换使用。

### 配置 V2 加密客户端
<a name="configure-the-v2-encryption-client"></a>

V2 加密客户端配置了一个 `CryptoConfigurationV2` 对象。可以通过调用其默认构造函数，然后根据需要修改其属性的默认值来构造此对象。

`CryptoConfigurationV2` 默认值如下所示：
+  `cryptoMode` = `CryptoMode.StrictAuthenticatedEncryption` 
+  `storageMode` = `CryptoStorageMode.ObjectMetadata` 
+  `secureRandom` = `SecureRandom` 的实例 
+  `rangeGetMode` = `CryptoRangeGetMode.DISABLED` 
+  `unsafeUndecryptableObjectPassthrough` = `false` 

请注意 *EncryptionOnly*，V2 加密客户端不支持`cryptoMode`该功能。V2 加密客户端将始终使用经过身份验证的加密来加密内容，并使用 V `KeyWrap` 2 对象保护内容加密密钥 (CEKs)。

以下示例演示如何在 V1 中指定加密配置，以及如何实例化 *CryptoConfigurationV2 对象以传递给 V2* 加密客户端生成器。

 **V1** 

```
CryptoConfiguration cryptoConfiguration = new CryptoConfiguration()
        .withCryptoMode(CryptoMode.StrictAuthenticatedEncryption);
```

 **V2** 

```
CryptoConfigurationV2 cryptoConfiguration = new CryptoConfigurationV2()
        .withCryptoMode(CryptoMode.StrictAuthenticatedEncryption);
```

## 其他示例
<a name="additional-examples"></a>

以下示例演示如何解决与从 V1 迁移到 V2 相关的特定用例。

### 将服务客户端配置为读取 V1 加密客户端创建的对象
<a name="configure-a-service-client-to-read-objects-created-by-the-v1-encryption-client"></a>

要读取以前使用 V1 加密客户端写入的对象，请将设置 `cryptoMode` 为 `AuthenticatedEncryption`。以下代码段演示如何使用此设置构造配置对象。

```
CryptoConfigurationV2 cryptoConfiguration = new CryptoConfigurationV2()
        .withCryptoMode(CryptoMode.AuthenticatedEncryption);
```

### 配置服务客户端以获取对象的字节范围
<a name="configure-a-service-client-to-get-byte-ranges-of-objects"></a>

要能够从加密的 S3 对象中 `get` 字节范围，请启用新的配置设置 `rangeGetMode`。默认情况下，此设置在 V2 加密客户端上处于禁用状态。请注意，即使启用了此设置，具有范围的 `get` 也只能对使用客户端 `cryptoMode` 设置支持的算法进行加密的对象起作用。有关更多信息，请参阅 适用于 Java 的 AWS SDK API 参考[CryptoRangeGetMode](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/CryptoRangeGetMode.html)中的。

如果您计划使用 V2 加密客户端 Amazon S3 TransferManager 对加密 Amazon S3 对象执行分段下载，则必须先在 V2 加密客户端上启用该`rangeGetMode`设置。

以下代码段演示如何配置 V2 客户端以执行具有范围的 `get`。

```
// Allows range gets using AES/CTR, for V2 encrypted objects only
CryptoConfigurationV2 cryptoConfiguration = new CryptoConfigurationV2()
       .withRangeGetMode(CryptoRangeGetMode.ALL);

// Allows range gets using AES/CTR and AES/CBC, for V1 and V2 objects
CryptoConfigurationV2 cryptoConfiguration = new CryptoConfigurationV2()
       .withCryptoMode(CryptoMode.AuthenticatedEncryption)
       .withRangeGetMode(CryptoRangeGetMode.ALL);
```