

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon S3 加密用戶端遷移 (V1 至 V2)
<a name="s3-encryption-migration-v1-v2"></a>

**注意**  
如果您使用的是 Amazon S3 加密用戶端的 V2，並且想要遷移至 V3，請參閱 [Amazon S3 加密用戶端遷移 (V2 到 V3)](s3-encryption-migration-v2-v3.md)。

本主題說明如何將應用程式從 Amazon Simple Storage Service (Amazon S3) 加密用戶端的第 1 版 (V1) 遷移到第 2 版 (V2)，並確保在整個遷移過程中的應用程式可用性。

## 遷移概觀
<a name="migration-overview-v1-v2"></a>

此遷移分為兩個階段：

1. **更新現有用戶端以讀取新格式。**首先，將更新的 適用於 C\+\+ 的 AWS SDK 版本部署到您的應用程式。這可讓現有的 V1 加密用戶端解密新 V2 用戶端寫入的物件。如果您的應用程式使用多個 AWS SDKs，您必須分別升級每個 SDK。

2. **將加密和解密用戶端遷移至 V2。**一旦所有 V1 加密用戶端都可以讀取新的格式，您就可以將現有的加密和解密用戶端遷移到各自的 V2 版本。

## 更新現有用戶端以讀取新格式
<a name="update-existing-clients-to-read-new-formats-v1-v2"></a>

您必須先將現有用戶端更新為最新的 SDK 版本。完成此步驟後，您應用程式的 V1 用戶端將能夠解密 V2 加密用戶端加密的物件，而無需更新應用程式的程式碼庫。

### 建置和安裝最新版本的 適用於 C\+\+ 的 AWS SDK
<a name="build-and-install-the-latest-version-of-the-sdk-cpp-v1-v2"></a>

 **從來源使用 SDK 的應用程式** 

如果您 適用於 C\+\+ 的 AWS SDK 從來源建置和安裝 ，請在 GitHub [`aws/aws-sdk-cpp`](https://github.com/aws/aws-sdk-cpp)上從 下載或複製 SDK 來源。然後重複正常的建置和安裝步驟。

如果您是 適用於 C\+\+ 的 AWS SDK 從早於 1.8.x 的版本升級，請參閱此 [CHANGELOG](https://github.com/aws/aws-sdk-cpp/blob/master/CHANGELOG.md)，了解在每個主要版本中引進的重大變更。如需如何建置和安裝 的詳細資訊 適用於 C\+\+ 的 AWS SDK，請參閱 [適用於 C\+\+ 的 AWS SDK 從原始程式碼取得](sdk-from-source.md)。

 **從 Vcpkg 使用 SDK 的應用程式** 

如果您的應用程式使用 [Vcpkg](https://github.com/microsoft/vcpkg) 來追蹤 SDK 更新，只需使用現有的 Vcpkg 升級方法來將 SDK 升級到最新版本。請記住，發行版本與透過套件管理員取得版本之間存在延遲。透過[從來源安裝](sdk-from-source.md) ，一律可使用最新版本。

您可以執行下列命令來升級套件 `aws-sdk-cpp`：

```
vcpkg upgrade aws-sdk-cpp
```

並驗證套件 的版本`aws-sdk-cpp`：

```
vcpkg list aws-sdk-cpp
```

版本應至少為 1.8.24。

如需搭配 使用 Vcpkg 的詳細資訊 適用於 C\+\+ 的 AWS SDK，請參閱 [適用於 C\+\+ 的 AWS SDK 從套件管理員取得](sdk-from-pm.md)。

### 建置、安裝和部署您的應用程式
<a name="build-install-and-deploy-your-applications-v1-v2"></a>

如果您的應用程式靜態連結至 適用於 C\+\+ 的 AWS SDK，則不需要在您的應用程式中進行程式碼變更，但您必須再次建置應用程式，才能使用最新的 SDK 變更。動態連結不需要此步驟。

升級應用程式的相依性版本並驗證應用程式功能後，請繼續將應用程式部署到機群。一旦應用程式部署完成，您就可以繼續進行下一個階段，遷移應用程式以使用 V2 加密和解密用戶端。

## 將加密和解密用戶端遷移至 V2
<a name="migrate-encryption-and-decryption-clients-to-v2-v1-v2"></a>

下列步驟說明如何成功將程式碼從 Amazon S3 加密用戶端的 V1 遷移至 V2。由於程式碼需要變更，因此無論應用程式是靜態還是動態連結，您都需要重建應用程式 適用於 C\+\+ 的 AWS SDK。

### 使用新的加密資料
<a name="using-new-encryption-materials-v1-v2"></a>

使用 V2 Amazon S3 加密用戶端和 V2 加密組態時，下列加密資料已棄用：
+  `SimpleEncryptionMaterials` 
+  `KMSEncryptionMaterials` 

它們已被下列安全加密資料取代：
+  `SimpleEncryptionMaterialsWithGCMAAD` 
+  `KMSWithContextEncryptionMaterials` 

建構 V2 S3 加密用戶端需要下列程式碼變更：
+   
**如果您在建立 S3 加密用戶端`KMSEncryptionMaterials`時使用 ：**  
  + 建立 V2 S3 加密用戶端時，`KMSEncryptionMaterials`請將 取代為 ，`KMSWithContextEncryptionMaterials`並在 V2 加密組態中指定。
  + 使用 V2 Amazon S3 加密用戶端放置物件時，您必須明確提供字串內容映射作為加密 CEK 的 KMS 內容。這可能是空的映射。
+   
**如果您在建立 S3 加密用戶端`SimpleEncryptionMaterials`時使用 ：**  
  + 建立 V2 Amazon S3 加密用戶端時，請將 取代`SimpleEncryptionMaterials`為 ，`SimpleEncryptionMaterialsWithGCMAAD`並在 V2 加密組態中指定。
  + 使用 V2 Amazon S3 加密用戶端放置物件時，您必須明確提供空白字串內容映射，否則 SDK 會傳回錯誤。

 **範例：使用 KMS/KMSWithContext 金鑰包裝演算法** 

 *預遷移 (KMS 金鑰包裝）* 

```
auto materials = Aws::MakeShared<KMSEncryptionMaterials>("s3Encryption", CUSTOMER_MASTER_KEY_ID);
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the putObjectRequest object.
encryptionClient.PutObject(putObjectRequest);
```

 *遷移後 (KMSWithContext 金鑰包裝）* 

```
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", CUSTOMER_MASTER_KEY_ID);
CryptoConfigurationV2 cryptoConfig(materials);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the putObjectRequest object.
Aws::Map<Aws::String, Aws::String> kmsContextMap;
kmsContextMap.emplace("client", "aws-sdk-cpp");
kmsContextMap.emplace("version", "1.8.0");
encryptionClient.PutObject(putObjectRequest, kmsContextMap /* could be empty as well */);
```

 **範例：使用 AES/AES-GCM 金鑰包裝演算法** 

 *預遷移 (AES 金鑰包裝）* 

```
auto materials = Aws::MakeShared<SimpleEncryptionMaterials>("s3Encryption", HashingUtils::Base64Decode(AES_MASTER_KEY_BASE64));
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the putObjectRequest object.
encryptionClient.PutObject(putObjectRequest);
```

 *遷移後 (AES-GCM 金鑰包裝）* 

```
auto materials = Aws::MakeShared<SimpleEncryptionMaterialsWithGCMAAD>("s3EncryptionV2", HashingUtils::Base64Decode(AES_MASTER_KEY_BASE64));
CryptoConfigurationV2 cryptoConfig(materials);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the putObjectRequest object.
encryptionClient.PutObject(putObjectRequest, {} /* must be an empty map */);
```

## 其他範例
<a name="additional-examples-v1-v2"></a>

下列範例示範如何解決與從 V1 遷移至 V2 相關的特定使用案例。

### 解密舊版 Amazon S3 加密用戶端加密的物件
<a name="decrypt-objects-encrypted-by-legacy-amazon-s3-encryption-clients-v1-v2"></a>

根據預設，您無法使用 V2 Amazon S3 加密用戶端來解密使用已取代的金鑰包裝演算法或已取代的內容加密結構描述進行加密的物件。

下列金鑰包裝演算法已棄用：
+  `KMS` 
+  `AES_KEY_WRAP` 

下列內容加密結構描述已棄用：
+  `CBC` 
+  `CTR` 

如果您在 中使用舊版 Amazon S3 加密用戶端 適用於 C\+\+ 的 AWS SDK 來加密物件，您可能會使用已棄用的方法，如果：
+ 您已使用 `SimpleEncryptionMaterials`或 `KMSEncryptionMaterials`。
+ 您在加密組態`Crypto Mode`中使用 `ENCRYPTION_ONLY`做為 。

若要使用 V2 Amazon S3 加密用戶端來解密已遭取代的金鑰包裝演算法或已取代的內容加密結構描述所加密的物件，您必須將 V2 加密組態`SecurityProfile`中的預設值從 覆寫`V2`為 `V2_AND_LEGACY`。

 **範例** 

 *預遷移* 

```
auto materials = Aws::MakeShared<KMSEncryptionMaterials>("s3Encryption", CUSTOMER_MASTER_KEY_ID);
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
encryptionClient.GetObject(getObjectRequest);
```

 *遷移後* 

```
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", CUSTOMER_MASTER_KEY_ID);
CryptoConfigurationV2 cryptoConfig(materials);
cryptoConfig.SetSecurityProfile(SecurityProfile::V2_AND_LEGACY);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
encryptionClient.GetObject(getObjectRequest);
```

### 使用範圍解密物件
<a name="decrypt-objects-with-range-v1-v2"></a>

使用舊版 Amazon S3 加密用戶端，您可以指定解密 S3 物件時要接收的位元組範圍。在 V2 Amazon S3 加密用戶端中，此功能預設為 `DISABLED` 。因此，您必須覆寫 V2 加密組態`ALL`中`RangeGetMode`從 `DISABLED`到 的預設值。

 **範例** 

 *預遷移* 

```
auto materials = Aws::MakeShared<KMSEncryptionMaterials>("s3Encryption", CUSTOMER_MASTER_KEY_ID);
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
getObjectRequest.WithRange("bytes=38-75");
encryptionClient.GetObject(getObjectRequest);
```

 *遷移後* 

```
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", CUSTOMER_MASTER_KEY_ID);
CryptoConfigurationV2 cryptoConfig(materials);
cryptoConfig.SetUnAuthenticatedRangeGet(RangeGetMode::ALL);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
getObjectRequest.WithRange("bytes=38-75");
encryptionClient.GetObject(getObjectRequest);
```

### 使用任何 CMK 解密物件
<a name="decrypt-objects-with-any-cmk-v1-v2"></a>

解密使用 加密的物件時`KMSWithContextEncryptionMaterials`，V2 Amazon S3 加密用戶端能夠提供空的主金鑰，讓 KMS 找到適當的 CMK。此功能預設為 `DISABLED` 。您必須針對 KMS `SetKMSDecryptWithAnyCMK(true)` 加密資料呼叫 ，明確設定它。

 **範例** 

 *預遷移* 

```
auto materials = Aws::MakeShared<KMSEncryptionMaterials>("s3Encryption", ""/* provide an empty KMS Master Key*/);
CryptoConfiguration cryptoConfig;
S3EncryptionClient encryptionClient(materials, cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
encryptionClient.GetObject(getObjectRequest);
```

 *遷移後* 

```
auto materials = Aws::MakeShared<KMSWithContextEncryptionMaterials>("s3EncryptionV2", ""/* provide an empty KMS Master Key*/);
materials.SetKMSDecryptWithAnyCMK(true);
CryptoConfigurationV2 cryptoConfig(materials);
S3EncryptionClientV2 encryptionClient(cryptoConfig);
// Code snippet here to setup the getObjectRequest object.
encryptionClient.GetObject(getObjectRequest);
```

如需所有這些遷移案例的完整程式碼，請參閱 Github 上的 [Amazon S3 加密範例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3encryption)。