

 适用于 .NET 的 Amazon SDK V3 已进入维护模式。

我们建议您迁移到 [适用于 .NET 的 Amazon SDK V4](https://docs.amazonaws.cn/sdk-for-net/v4/developer-guide/welcome.html)。有关如何迁移的更多详细信息和信息，请参阅我们的[维护模式公告](https://www.amazonaws.cn/blogs/developer/aws-sdk-for-net-v3-maintenance-mode-announcement/)。

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

# 亚马逊 S3 加密客户端迁移（从 V1 到 V2）
S3 加密客户端迁移（从 V1 到 V2）

**注意**  
如果您使用的是 V2 并希望迁移到 V4，请参阅。[亚马逊 S3 加密客户端迁移（从 V2 到 V4）](s3-encryption-migration-v2-v4.md)

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

使用 V2 客户端加密的对象无法使用 V1 客户端解密。为了便于迁移到新客户端，而不必同时重新加密所有对象，我们提供了“V1 过渡”客户端。此客户端可以*解密* V1 和 V2 加密的对象，但只能*加密*与 V1 兼容的格式的对象。V2 客户端可以*解密* V1 和 V2 加密的对象（当为 V1 对象启用时），但只能*加密*与 V2 兼容的格式的对象。

## 迁移概述


这种迁移分三个阶段进行。此处将介绍这些阶段，稍后将详细介绍。在下一阶段开始之前，必须完成*所有*使用共享对象的客户端的每个阶段。

1. **将现有客户端更新为 V1 过渡客户端以读取新格式。**首先，更新您的应用程序，使其依赖于 V1 过渡客户端，而不是 V1 客户端。V1 过渡客户端使您的现有代码能够解密新 V2 客户端编写的对象和以 V1 兼容格式编写的对象。
**注意**  
V1 过渡客户端仅用于迁移目的。移至 V1 过渡客户端后，继续升级到 V2 客户端。

1. **将 V1 过渡客户端迁移到 V2 客户端以编写新格式。**接下来，将应用程序中的所有 V1 过渡客户端替换为 V2 客户端，并将安全配置文件设置为 `V2AndLegacy`。在 V2 客户端上设置此安全配置文件可使这些客户端解密以 V1 兼容格式加密的对象。

1. **更新 V2 客户端，使其不再读取 V1 格式。**最后，在所有客户端都迁移到 V2 并且所有对象都已以 V2 兼容格式加密或重新加密之后，请将 V2 安全配置文件设置为 `V2` 而不是 `V2AndLegacy`。这可以防止解密 V1 兼容格式的对象。

## 将现有客户端更新为 V1 过渡客户端以读取新格式


V2 加密客户端使用旧版本客户端不支持的加密算法。迁移的第一步是更新您的 V1 解密客户端，以便它们可以读取新格式。

V1 过渡客户端使您的应用程序能够解密 V1 和 V2 加密的对象。此客户端是 [Amazon.Extensions.S3.Encryption 软件包的一部分。](https://www.nuget.org/packages/Amazon.Extensions.S3.Encryption) NuGet 在每个应用程序上执行以下步骤以使用 V1 过渡客户端。

1. 接受 [Amazon.Extensions.S3.Encryption](https://www.nuget.org/packages/Amazon.Extensions.S3.Encryption) 程序包的依赖项。**如果您的项目直接依赖于 **AWSSDK.S3** 或AWSSDK. KeyManagementService**软件包，您必须更新这些依赖项或将其删除，以便将它们的更新版本与这个新软件包一起引入。

1. 将相应的 `using` 语句从 `Amazon.S3.Encryption` 更改为 `Amazon.Extensions.S3.Encryption`，如下所示：

   ```
   // using Amazon.S3.Encryption;
     using Amazon.Extensions.S3.Encryption;
   ```

1. 重新构建并重新部署您的应用程序。

V1 过渡客户端与 V1 客户端的 API 完全兼容，因此无需更改其它代码。

## 将 V1 过渡客户端迁移到 V2 客户端以写入新格式


V2 客户端是 A [mazon.extens.](https://www.nuget.org/packages/Amazon.Extensions.S3.Encryption) NuGet S3.Encryption 软件包的一部分。它使您的应用程序能够解密 V1 和 V2 加密的对象（如果配置为这样做），但只能加密 V2 兼容格式的对象。

更新现有客户端以读取新的加密格式后，您可以继续将应用程序安全更新到 V2 加密和解密客户端。在每个应用程序上执行以下步骤以使用 V2 客户端：

1. 将 `EncryptionMaterials` 更改为 `EncryptionMaterialsV2`。

   1. 使用 KMS 时：

      1. 提供 KMS 密钥 ID。

      1. 声明您正在使用的加密方法；即 `KmsType.KmsContext`。

      1. 向 KMS 提供与该数据密钥关联的加密上下文。您可以发送空字典（Amazon 加密上下文仍将合并到其中），但鼓励提供更多上下文。

   1. 使用用户提供的密钥封装方法（对称或非对称加密）时：

      1. 提供包含加密材料的 `AES` 或 `RSA` 实例。

      1. 声明要使用哪种加密算法；也就是说，`SymmetricAlgorithmType.AesGcm` 还是 `AsymmetricAlgorithmType.RsaOaepSha1`。

1. 将 `AmazonS3CryptoConfiguration` 更改为 `AmazonS3CryptoConfigurationV2`，`SecurityProfile` 属性设置为 `SecurityProfile.V2AndLegacy`。

1. 将 `AmazonS3EncryptionClient` 更改为 `AmazonS3EncryptionClientV2`。此客户端采用前面步骤中新转换的 `AmazonS3CryptoConfigurationV2` 和 `EncryptionMaterialsV2` 对象。

### 示例：KMS 到 KMS\$1Context


**迁移前**

```
using System.Security.Cryptography;
using Amazon.S3.Encryption;

var encryptionMaterial = new EncryptionMaterials("1234abcd-12ab-34cd-56ef-1234567890ab");
var configuration = new AmazonS3CryptoConfiguration()
{
    StorageMode = CryptoStorageMode.ObjectMetadata
};
var encryptionClient = new AmazonS3EncryptionClient(configuration, encryptionMaterial);
```

**迁移后**

```
using System.Security.Cryptography;
using Amazon.Extensions.S3.Encryption;
using Amazon.Extensions.S3.Encryption.Primitives;

var encryptionContext = new Dictionary<string, string>();
var encryptionMaterial = new EncryptionMaterialsV2("1234abcd-12ab-34cd-56ef-1234567890ab", KmsType.KmsContext, encryptionContext);
var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy)
{
    StorageMode = CryptoStorageMode.ObjectMetadata
};
var encryptionClient = new AmazonS3EncryptionClientV2(configuration, encryptionMaterial);
```

### 示例：对称算法（AES-CBC 到 AES-GCM 密钥封装）


`StorageMode` 可以是 `ObjectMetadata` 或 `InstructionFile`。

**迁移前**

```
using System.Security.Cryptography;
using Amazon.S3.Encryption;

var symmetricAlgorithm = Aes.Create();
var encryptionMaterial = new EncryptionMaterials(symmetricAlgorithm);
var configuration = new AmazonS3CryptoConfiguration()
{
    StorageMode = CryptoStorageMode.ObjectMetadata
};
var encryptionClient = new AmazonS3EncryptionClient(configuration, encryptionMaterial);
```

**迁移后**

```
using System.Security.Cryptography;
using Amazon.Extensions.S3.Encryption;
using Amazon.Extensions.S3.Encryption.Primitives;

var symmetricAlgorithm = Aes.Create();
var encryptionMaterial = new EncryptionMaterialsV2(symmetricAlgorithm, SymmetricAlgorithmType.AesGcm);
var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy)
{
    StorageMode = CryptoStorageMode.ObjectMetadata
};
var encryptionClient = new AmazonS3EncryptionClientV2(configuration, encryptionMaterial);
```

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

### 示例：非对称算法（RSA 到 RSA-OAEP-SHA 1 密钥封装）


`StorageMode` 可以是 `ObjectMetadata` 或 `InstructionFile`。

**迁移前**

```
using System.Security.Cryptography;
using Amazon.S3.Encryption;

var asymmetricAlgorithm = RSA.Create();
var encryptionMaterial = new EncryptionMaterials(asymmetricAlgorithm);
var configuration = new AmazonS3CryptoConfiguration()
{
    StorageMode = CryptoStorageMode.ObjectMetadata
};
var encryptionClient = new AmazonS3EncryptionClient(configuration, encryptionMaterial);
```

**迁移后**

```
using System.Security.Cryptography;
using Amazon.Extensions.S3.Encryption;
using Amazon.Extensions.S3.Encryption.Primitives;

var asymmetricAlgorithm = RSA.Create();
var encryptionMaterial = new EncryptionMaterialsV2(asymmetricAlgorithm, AsymmetricAlgorithmType.RsaOaepSha1);
var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy)
{
    StorageMode = CryptoStorageMode.ObjectMetadata
};
var encryptionClient = new AmazonS3EncryptionClientV2(configuration, encryptionMaterial);
```

## 将 V2 客户端更新为不再读取 V1 格式


最终，所有对象都将使用 V2 客户端进行加密或重新加密。*转换完成后*，您可以通过将 `SecurityProfile` 属性设置为 `SecurityProfile.V2`，在 V2 客户端中禁用 V1 兼容性，如以下代码片段所示。

```
//var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy);
var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2);
```