

 适用于 .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 加密客户端迁移（从 V2 到 V4）
S3 加密客户端迁移（从 V2 到 V4）S3 加密客户端 V4 迁移

添加了有关从 V2 迁移到 V4 的信息。

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

本主题介绍如何将您的应用程序从亚马逊简单存储服务 (Amazon S3) Simple Service 加密客户端的版本 2 (V2) 迁移到版本 4 (V4)，并确保应用程序在整个迁移过程中的可用性。V4 使用带有密钥承诺的 AES-GCM 进行内容加密，并引入了承诺策略来增强针对密钥替换攻击的安全性。

V4 客户端在 A [mazon.extens.](https://www.nuget.org/packages/Amazon.Extensions.S3.Encryption) NuGet S3.Encryptions 软件包中可用。

**重要**  
**重大更改：**使用`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`策略配置的 V4 客户端无法解密使用 V1 或 V2 客户端加密的对象。只有最新的 V2 客户端才能使用密钥承诺解密 v4 加密的对象。在转向`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`策略之前，您必须使用启用密钥承诺的 V4 客户端重新加密所有现有数据。

## 理解 V4 概念


V4 使用带有密钥承诺的 AES-GCM 进行内容加密，并引入了增强加密数据保护的关键安全概念：

### 承诺政策


承诺策略控制加密客户端在加密和解密操作期间如何处理密钥承诺。V4 支持三种承诺策略：

`FORBID_ENCRYPT_ALLOW_DECRYPT`  
*加密：*无需承诺  
*解密：*允许不提交对象  
*安全：*不强制承诺，可能允许篡改  
*兼容性：*所有 V2 和 V4 实现都可以读取使用此策略加密的对象

`REQUIRE_ENCRYPT_ALLOW_DECRYPT`  
*加密：*使用密钥承诺  
*解密：*允许提交和不提交对象  
*安全：*保护新对象免受密钥替换攻击，旧对象仍然可读  
*兼容性：*只有 V4 支持此政策

`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`（V4 的默认设置）  
*加密：*使用密钥承诺  
*解密：仅提交*对象  
*安全：*全面执行承诺，最大限度地提高安全性  
*兼容性：*只有 V4 支持此政策

### 带有关键承诺的 AES GCM


V4 使用带有密钥承诺的 AES-GCM 进行内容加密，从而增强了安全性：
+ *篡改保护：*它通过加密方式将密钥绑定到加密数据来防止密钥替换攻击。
+ *版本兼容性：*使用密钥承诺加密的对象只能由 V4 客户端和更高版本解密。

**警告**  
在生产环境中启用密钥承诺加密之前，请确保所有需要解密对象的应用程序都已升级到 V4 或更高版本，因为 V2 客户端已被弃用。

## 更新现有客户端以读取 V4 格式


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

### 更新 Pac NuGet kage 依赖关系


更新您的应用程序以使用包含 V4 支持的最新版本的 [Amazon.extensions.S3.Encryption 软件包](https://www.nuget.org/packages/Amazon.Extensions.S3.Encryption) NuGet 。对每个应用程序执行以下步骤：

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

1. 确保您的`using`语句引用了正确的命名空间：

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

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

您现有的 V2 客户端将继续使用更新的软件包，并且能够解密由 V4 客户端加密的对象（取决于所使用的承诺策略）。

### 构建和部署应用程序


更新 NuGet 软件包依赖关系后：

1. 构建您的应用程序以确保正确解析所有依赖关系。

1. 在开发环境中测试您的应用程序，以验证现有功能是否可以继续运行。

1. 将更新的应用程序部署到您的生产环境。

此更新使您现有的 V2 客户端能够解密将由 V4 客户端加密的对象，从而确保迁移过程中的兼容性。

## 迁移到 V4 客户端


更新现有客户端以读取新的加密格式后，您可以继续安全地更新应用程序以使用 V4 加密和解密客户端。V4 客户端通过密钥承诺提供增强的安全性，同时保持与现有加密对象的兼容性。

### 4 步迁移流程


从 V2 迁移到 V4 遵循结构化的 4 步流程，以确保兼容性和安全性。每个步骤都代表一个特定的配置，在继续下一步之前，应在所有应用程序中部署该配置。

1. **步骤 0：V2 客户端（起点）**-您现有的 V2 实现

1. **第 1 步：具有 V2 兼容性的 V4**-迁移到 V4 客户端，同时保持与 V2 兼容的加密行为

1. **第 2 步：使用密钥承诺写入的 V4**-开始使用密钥承诺进行加密，同时允许解密旧对象

1. **第 3 步：具有全面强制功能的 V4**-加密和解密都需要密钥承诺

### 步骤 0：V2 客户端（起点）


这代表您现有的 V2 客户端配置。此步骤演示迁移前的起始状态。

```
using Amazon.Extensions.S3.Encryption;
using Amazon.Extensions.S3.Encryption.Primitives;
using Amazon.S3.Model;

// Step 0: V2 Client - Starting configuration
var encryptionContext = new Dictionary<string, string>();
var encryptionMaterial = new EncryptionMaterialsV2(kmsKeyId, KmsType.KmsContext, encryptionContext);

#pragma warning disable 0618
var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2);
#pragma warning enable 0618

var encryptionClient = new AmazonS3EncryptionClientV2(configuration, encryptionMaterial);

// Use the client for PutObject and GetObject operations
await encryptionClient.PutObjectAsync(new PutObjectRequest
{
    BucketName = bucket,
    Key = objectKey,
    ContentBody = content
});
```

### 第 1 步：具有 V2 兼容性的 V4


迁移到 V4 客户端，同时保持与 V2 相同的行为。此步骤使用`FORBID_ENCRYPT_ALLOW_DECRYPT`策略进行加密，无需承诺即可进行加密，并允许对所有对象进行解密。

```
using Amazon.Extensions.S3.Encryption;
using Amazon.Extensions.S3.Encryption.Primitives;
using Amazon.S3.Model;

// Step 1: V4 Client with V2 compatibility
var encryptionContext = new Dictionary<string, string>();
var encryptionMaterial = new EncryptionMaterialsV4(kmsKeyId, KmsType.KmsContext, encryptionContext);

var configuration = new AmazonS3CryptoConfigurationV4(
    SecurityProfile.V4, 
    CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT, 
    ContentEncryptionAlgorithm.AesGcm);

var encryptionClient = new AmazonS3EncryptionClientV4(configuration, encryptionMaterial);

// Use the client for PutObject and GetObject operations
await encryptionClient.PutObjectAsync(new PutObjectRequest
{
    BucketName = bucket,
    Key = objectKey,
    ContentBody = content
});
```

**行为：**无需承诺即可加密，可以解密已提交和未提交的对象。与 V2 行为相同。

### 第 2 步：带有关键承诺写入的 V4


使用密钥承诺开始加密，同时保持解密的向后兼容性。此步骤使用`REQUIRE_ENCRYPT_ALLOW_DECRYPT`策略。

**警告**  
在部署步骤 2 之前，请确保所有读取器都已更新到步骤 1 或更高版本以处理密钥承诺加密。

```
using Amazon.Extensions.S3.Encryption;
using Amazon.Extensions.S3.Encryption.Primitives;
using Amazon.S3.Model;

// Step 2: V4 Client with key commitment writes
var encryptionContext = new Dictionary<string, string>();
var encryptionMaterial = new EncryptionMaterialsV4(kmsKeyId, KmsType.KmsContext, encryptionContext);

var configuration = new AmazonS3CryptoConfigurationV4(
    SecurityProfile.V4, 
    CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT, 
    ContentEncryptionAlgorithm.AesGcmWithCommitment);

var encryptionClient = new AmazonS3EncryptionClientV4(configuration, encryptionMaterial);

// Use the client for PutObject and GetObject operations
await encryptionClient.PutObjectAsync(new PutObjectRequest
{
    BucketName = bucket,
    Key = objectKey,
    ContentBody = content
});
```

**行为：**使用承诺进行加密，可以解密已提交和未提交的对象。保护新对象免受密钥替换攻击。

### 第 3 步：全面强制执行的 V4


加密和解密都需要密钥承诺。此步骤使用`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`策略来最大限度地提高安全性。

**警告**  
在部署步骤 3 之前，请确保系统中的所有对象都已使用密钥承诺重新加密（步骤 2）。此步骤将无法解密未经承诺加密的对象。

```
using Amazon.Extensions.S3.Encryption;
using Amazon.Extensions.S3.Encryption.Primitives;
using Amazon.S3.Model;

// Step 3: V4 Client with full key commitment enforcement
var encryptionContext = new Dictionary<string, string>();
var encryptionMaterial = new EncryptionMaterialsV4(kmsKeyId, KmsType.KmsContext, encryptionContext);

var configuration = new AmazonS3CryptoConfigurationV4(
    SecurityProfile.V4, 
    CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT, 
    ContentEncryptionAlgorithm.AesGcmWithCommitment);

var encryptionClient = new AmazonS3EncryptionClientV4(configuration, encryptionMaterial);

// Use the client for PutObject and GetObject operations
await encryptionClient.PutObjectAsync(new PutObjectRequest
{
    BucketName = bucket,
    Key = objectKey,
    ContentBody = content
});
```

**行为：**使用承诺进行加密，仅解密使用承诺加密的对象。最大限度地抵御密钥替换攻击。

## 其他配置示例


本节提供了在迁移期间使用不同选项配置 V4 客户端的其他示例。

### 启用旧版 Support


要使 V4 客户端能够读取由 V1 和 V2 客户端加密的对象，请使用允许旧版解密的承诺策略配置客户端：

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

// Configure V4 client to read V1/V2 objects
var configuration = new AmazonS3CryptoConfigurationV4(CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT)
{
    StorageMode = CryptoStorageMode.ObjectMetadata
};

// This configuration allows:
// - Encryption: With commitment (secure)
// - Decryption: Both V2 (non-committing) and V4 (committing) objects
```

当您需要解密由旧客户机加密的对象，同时确保以增强的安全性对新对象进行加密时，请在迁移期间使用此配置。

### 配置存储方法


V4 支持两种存储方法来存储加密元数据。选择最适合您的用例的方法：

**对象元数据（默认）**

```
var configuration = new AmazonS3CryptoConfigurationV4(CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT)
{
    StorageMode = CryptoStorageMode.ObjectMetadata
};
// Encryption metadata is stored in S3 object metadata
```

**指令文件**

```
var configuration = new AmazonS3CryptoConfigurationV4(CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT)
{
    StorageMode = CryptoStorageMode.InstructionFile
};
// Encryption metadata is stored in a separate S3 object (instruction file)
```

`InstructionFile`当您需要为其他目的保留对象元数据或处理有元数据大小限制的对象时使用。

### 配置承诺策略


根据您的安全要求和迁移阶段选择适当的承诺策略：

**迁移阶段（V2 兼容性）**

```
// For migration: encrypt without commitment, allow all decryption
var migrationConfig = new AmazonS3CryptoConfigurationV4(CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT);
```

**过渡阶段（推荐）**

```
// For transition: encrypt with commitment, allow legacy decryption
var transitionConfig = new AmazonS3CryptoConfigurationV4(CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT);
```

**完整安全阶段**

```
// For maximum security: require commitment for both encryption and decryption
var secureConfig = new AmazonS3CryptoConfigurationV4(CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT);
```

从初始迁移`FORBID_ENCRYPT_ALLOW_DECRYPT`期间开始，进入过渡阶段，最后`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`在所有客户端都已升级并且所有对象都已通过承诺重新加密后使用。`REQUIRE_ENCRYPT_ALLOW_DECRYPT`