

 適用於 Java 的 AWS SDK 1.x 已於 2025 年 12 月 31 日end-of-support。我們建議您遷移至 [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 版 Amazon Simple Storage Service (V1 Amazon S3) 遷移到第 2 版 (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)和 Open Java 開發套件 (OpenJDK) 的發行版本，例如 [Amazon Corretto](https://aws.amazon.com/corretto/)、[Red Hat OpenJDK](https://developers.redhat.com/products/openjdk) 和 [AdoptOpenJDK](https://adoptopenjdk.net/)。
+ [Bouncy Castle Crypto 套件](https://www.bouncycastle.org/download/bouncy-castle-java/)。您可以在應用程式環境的 classpath 上放置 Bouncy Castle .jar 檔案，或將對 artifactId `bcprov-ext-jdk15on`（具有 的 groupId`org.bouncycastle`) 的相依性新增至 Maven `pom.xml` 檔案。

## 遷移概觀
<a name="s3-cse-overview"></a>

此遷移分為兩個階段：

1.  **更新現有用戶端以讀取新格式。**更新您的應用程式以使用 1.11.837 版或更新版本， 適用於 Java 的 AWS SDK 並重新部署應用程式。這可讓應用程式中的 Amazon S3 用戶端加密服務用戶端解密 V2 服務用戶端建立的物件。如果您的應用程式使用多個 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 參考 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>

您可以透過呼叫 AmazonS3EncryptionClientV2.encryptionBuilder() 來建構 V2 加密用戶端。 *AmazonS3EncryptionClientV2.encryptionBuilder().*

您可以使用 V2 加密用戶端取代所有現有的 V1 加密用戶端。 V2 只要您允許 V2 加密用戶端使用 `AuthenticatedEncryption``cryptoMode`，V2 加密用戶端一律可以讀取 V1 加密用戶端寫入的任何物件。

建立新的 V2 加密用戶端與建立 V1 加密用戶端的方式非常類似。不過，有幾個差異：
+ 您將使用`CryptoConfigurationV2`物件來設定用戶端，而非`CryptoConfiguration`物件。此為必要參數。
+ V2 加密用戶端`cryptoMode`的預設設定為 `StrictAuthenticatedEncryption`。對於 V1 加密用戶端，它是 `EncryptionOnly`。
+ 加密用戶端建置器上*withEncryptionMaterials()* 的方法已重新命名為 *withEncryptionMaterialsProvider()*。這只是一種外觀變更，可更準確地反映引數類型。設定服務用戶端時，您必須使用新的 方法。

**注意**  
使用 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` 

請注意，`cryptoMode`V2 加密用戶端不支援 *EncryptionOnly*。V2 加密用戶端一律會使用已驗證的加密來加密內容，並使用 V2 `KeyWrap` 物件來保護內容加密金鑰 (CEKs)。

下列範例示範如何在 V1 中指定加密組態，以及如何執行個體化要傳遞給 V2 *CryptoConfigurationV2*2 物件。 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)。

如果您打算使用 Amazon S3 TransferManager 使用 V2 加密用戶端執行加密 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);
```