

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

# AWS Encryption SDK 对于.NET
<a name="dot-net"></a>

fo AWS Encryption SDK r .NET 是一个客户端加密库，适用于使用 C\$1 和其他.NET 编程语言编写应用程序的开发人员。它在 Windows、macOS 和 Linux 上受支持。

**注意**  
 AWS Encryption SDK 适用于.NET 的 4.0.0 版本与《消息规范》 AWS Encryption SDK 有所不同。因此，由 4.0.0 版加密的消息只能通过.NET 版本 4.0.0 或更高版本进行解密。 AWS Encryption SDK 任何其他编程语言都无法对其进行解密。  
for .NET AWS Encryption SDK 的 4.0.1 版根据消息规范写入 AWS Encryption SDK 消息，并且可与其他编程语言实现互操作。默认情况下，版本 4.0.1 可以读取版本 4.0.0 加密的消息。但如果您不想解密由版本 4.0.0 加密的消息，则可以指定 [https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples/NetV4_0_0Example.cs](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples/NetV4_0_0Example.cs) 属性来阻止客户端读取这些消息。有关更多信息，请参阅 aws-encryption-sdk存储库中的 [v4.0.1 版本说明](https://github.com/aws/aws-encryption-sdk/releases/tag/v4.0.1)。 GitHub

f AWS Encryption SDK or .NET 与其他一些编程语言实现的不同之处 AWS Encryption SDK 在于：
+ 不支持[数据密钥缓存](data-key-caching.md)
**注意**  
版本 4。 .NET AWS Encryption SDK 的 *x* 支持[AWS KMS 分层密钥环](use-hierarchical-keyring.md)，这是一种替代的加密材料缓存解决方案。
+ 不支持流数据
+ 来自适用于 .NET 的 AWS Encryption SDK 的[无日志记录或堆栈跟踪](#dot-net-debugging)
+ [需要 适用于 .NET 的 AWS SDK](#dot-net-install)

.N AWS Encryption SDK ET 版包括 2.0 版中引入的所有安全功能。 *x* 及更高版本的其他语言实现 AWS Encryption SDK。但是，如果您使用 for .NET 来解密由 2.0 之前版本加密的数据。 AWS Encryption SDK *x* 版本的另一种语言实现 AWS Encryption SDK，您可能需要调整[承诺政策](concepts.md#commitment-policy)。有关更多信息，请参阅 [如何设置您的承诺策略](migrate-commitment-policy.md#migrate-commitment-step1)。

f AWS Encryption SDK or .NET 是 [Dafny AWS Encryption SDK](https://github.com/dafny-lang/dafny/blob/master/README.md) 中的产物，这是一种正式的验证语言，你可以用它来编写规范、实现规范的代码以及测试规范。结果为在确保功能正确性的框架中实施 AWS Encryption SDK 功能的库。

**了解更多**
+ 有关显示如何在中配置选项（例如指定备用算法套件 AWS Encryption SDK、限制加密数据密钥和使用 AWS KMS 多区域密钥）的示例，请参阅[正在配置 AWS Encryption SDK](configure.md)。
+ 有关使用 for .NET AWS Encryption SDK 进行编程的详细信息，请参阅上的 aws-encryption-sdk存储库[https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/)目录 GitHub。

**Topics**
+ [安装和构建](#dot-net-install)
+ [调试](#dot-net-debugging)
+ [示例](dot-net-examples.md)

## AWS Encryption SDK 为.NET 安装的
<a name="dot-net-install"></a>

.N AWS Encryption SDK ET 版作为[https://www.nuget.org/packages/AWS.Cryptography.EncryptionSDK](https://www.nuget.org/packages/AWS.Cryptography.EncryptionSDK)软件包提供 NuGet。有关安装和构建.NET 版的 AWS Encryption SDK 详细信息，请参阅存储库中的 [README.md](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/#readme) 文件。`aws-encryption-sdk-net`

**版本 3.x**  
版本 3。 .NET 版 AWS Encryption SDK 的 *x* 仅在 Windows 上支持.NET 框架 4.5.2 — 4.8。其在所有支持的操作系统中均支持 .NET Core 3.0\$1 和 .NET 5.0 及更高版本。

**版本 4.x**  
版本 4。 .NET 的 * AWS Encryption SDK x* 支持.NET 6.0 和.NET Framework net48 及更高版本。版本 4。 *x* 需要适用于.NET 的 AWS SDK v3。

**版本 5.x**  
版本 5。 .NET 的 * AWS Encryption SDK x* 支持.NET 6.0 和.NET Framework net48 及更高版本。版本 5。 *x* 需要版本 2。 材质提供者库 (MPL) 中的 *x* 和适用于.NET 的 AWS SDK v4。

 适用于 .NET 的 SDK 即使你没有使用 AWS Key Management Service (AWS KMS) 键，for .NET 也需要。 AWS Encryption SDK 它与 NuGet 软件包一起安装。但是，除非您使用的是 AWS KMS 密钥， AWS Encryption SDK 否则.NET 不需要 AWS 凭据或与任何 AWS 服务的交互。 AWS 账户如需有关设置 AWS 账户的帮助，请参阅[使用 wit AWS Encryption SDK h AWS KMS](getting-started.md)。

## AWS Encryption SDK 为.NET 调试
<a name="dot-net-debugging"></a>

fo AWS Encryption SDK r .NET 不生成任何日志。.NET 中的 AWS Encryption SDK 异常会生成异常消息，但不会生成堆栈跟踪。

为了帮助您进行调试，请务必在 适用于 .NET 的 SDK中启用日志记录功能。中的日志和错误消息 适用于 .NET 的 SDK 可以帮助您区分.NET 中出现的 适用于 .NET 的 SDK 错误和.NET 中出现 AWS Encryption SDK 的错误。有关 适用于 .NET 的 SDK 日志记录的帮助，请参阅[AWSLogging](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-config-other.html#config-setting-awslogging)《*适用于 .NET 的 AWS SDK 开发人员指南》*。（要查看该主题，请展开 **Open to view .NET Framework content** 部分。）

# AWS Encryption SDK 查看.NET 示例
<a name="dot-net-examples"></a>

以下示例显示了您在使用 for .NET AWS Encryption SDK 进行编程时使用的基本编码模式。具体而言，您可以实例化材料提供者库 AWS Encryption SDK 和材料提供者库。然后，在调用每个方法之前，首先实例化定义该方法输入的对象。这与您在 适用于 .NET 的 SDK中使用的编码模式非常相似。

有关显示如何在中配置选项（例如指定备用算法套件 AWS Encryption SDK、限制加密数据密钥和使用 AWS KMS 多区域密钥）的示例，请参阅[正在配置 AWS Encryption SDK](configure.md)。

有关使用 for .NET AWS Encryption SDK 进行编程的更多[示例，请参阅上`aws-encryption-sdk`存储库`aws-encryption-sdk-net`目录中的示例](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples) GitHub。

## 加密.NET 中的 AWS Encryption SDK 数据
<a name="dot-net-example-encrypt"></a>

此示例说明了数据加密的基本模式。它使用受一个 AWS KMS 包装密钥保护的数据密钥对一个小文件进行加密。

第 1 步：实例化材料提供者库 AWS Encryption SDK 和材料提供者库。  
首先实例化材料提供者库 AWS Encryption SDK 和材料提供者库。您将使用中的方法 AWS Encryption SDK 来加密和解密数据。您将使用材料提供程序库中的方法创建密钥环，密钥环指定哪些密钥保护您的数据。  
在版本 3 中，实例化材料提供者库 AWS Encryption SDK 和材质提供者库的方式有所不同。 *x* 和 4。 .NET AWS Encryption SDK 的 *x*。两个版本 3 的以下所有步骤都相同。 *x* 和 4。 .NET AWS Encryption SDK 的 *x*。  

```
// Instantiate the AWS Encryption SDK and material providers
var encryptionSdk = AwsEncryptionSdkFactory.CreateDefaultAwsEncryptionSdk();
var materialProviders =
    AwsCryptographicMaterialProvidersFactory.CreateDefaultAwsCryptographicMaterialProviders();
```

```
// Instantiate the AWS Encryption SDK and material providers
var esdk =  new ESDK(new AwsEncryptionSdkConfig());
var mpl = new MaterialProviders(new MaterialProvidersConfig());
```

步骤 2：为密钥环创建输入对象。  
每个密钥环创建方法均有对应的输入对象类。例如，要为 `CreateAwsKmsKeyring()` 方法创建输入对象，请创建 `CreateAwsKmsKeyringInput` 类的实例。  
尽管此密钥环的输入未指定[生成器密钥](use-kms-keyring.md#kms-keyring-encrypt)，但 `KmsKeyId` 参数指定的单个 KMS 密钥即为生成器密钥。其生成并加密进行数据加密的数据密钥。  
此输入对象需要 AWS KMS 客户端来获取 KMS 密钥。 AWS 区域 要创建 AWS KMS 客户端，请在中实例化该`AmazonKeyManagementServiceClient`类。 适用于 .NET 的 SDK调用不带参数的 `AmazonKeyManagementServiceClient()` 构造函数会创建具有默认值的客户端。  
在 AWS Encryption SDK 用于.NET 加密的密 AWS KMS 钥环中，您可以使用密钥 ID、[密钥 ARN、别名或别名 ARN 来识别](use-kms-keyring.md#kms-keyring-id) KMS 密钥。在用于解密的密 AWS KMS 钥环中，必须使用密钥 ARN 来识别每个 KMS 密钥。如果您计划重复使用加密密钥环进行解密，请将密钥 ARN 标识符用于所有 KMS 密钥。  

```
string keyArn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";

// Instantiate the keyring input object
var kmsKeyringInput = new CreateAwsKmsKeyringInput
{    
    KmsClient = new AmazonKeyManagementServiceClient(),
    KmsKeyId = keyArn
};
```

步骤 3：创建密钥环。  
要创建密钥环，请使用密钥环输入对象调用密钥环方法。此示例使用 `CreateAwsKmsKeyring()` 方法，该方法只需一个 KMS 密钥。  

```
var keyring = materialProviders.CreateAwsKmsKeyring(kmsKeyringInput);
```

步骤 4：定义加密上下文。  
[加密上下文](concepts.md#encryption-context)是可选的，但强烈建议在中进行加密操作。 AWS Encryption SDK您可以定义一个或多个非机密键值对。  
使用版本 4。 *x* AWS Encryption SDK 对于.NET，您可以使用所需的加密上下文 [CMM 在所有加密请求中要求使用加密上下文](configure.md#config-required-encryption-context-cmm)。

```
// Define the encryption context
var encryptionContext = new Dictionary<string, string>()
{
    {"purpose", "test"}
};
```

步骤 5：创建用于加密的输入对象。  
在调用 `Encrypt()` 方法之前，请创建 `EncryptInput` 类实例。  

```
string plaintext = File.ReadAllText("C:\\Documents\\CryptoTest\\TestFile.txt");
            
// Define the encrypt input
var encryptInput = new EncryptInput
{
    Plaintext = plaintext,
    Keyring = keyring,
    EncryptionContext = encryptionContext
};
```

步骤 6：加密明文。  
使用`Encrypt()`的方法，使用您定义 AWS Encryption SDK 的密钥环对纯文本进行加密。  
`Encrypt() ` 方法返回的 `EncryptOutput` 包含用于获取加密消息 (`Ciphertext`)、加密上下文和算法套件的方法。  

```
var encryptOutput = encryptionSdk.Encrypt(encryptInput);
```

步骤 7：获取加密消息。  
for .N AWS Encryption SDK ET 中的`Decrypt()`方法采用`EncryptOutput`实例`Ciphertext`的成员。  
`EncryptOutput` 对象的 `Ciphertext` 成员是[加密消息](concepts.md#message)，其为便携式对象，其中包括加密数据、加密数据密钥和元数据，包括加密上下文。您可以长时间安全存储加密消息，也可以将其提交给 `Decrypt()` 方法以便恢复明文。  

```
var encryptedMessage = encryptOutput.Ciphertext;
```

## 在 for .NET 中以严格模式解密 AWS Encryption SDK
<a name="dot-net-decrypt-strict"></a>

最佳实践建议您指定用于解密数据的密钥，该选项称为*严格模式*。仅 AWS Encryption SDK 使用您在密钥环中指定的 KMS 密钥来解密密文。解密密钥环中的密钥必须包含至少一个加密数据的密钥。

此示例说明了使用适用于 .NET 的 AWS Encryption SDK 在严格模式下进行解密的基本模式。

第 1 步：实例化 AWS Encryption SDK 和材料提供者库。  

```
// Instantiate the AWS Encryption SDK and material providers
var esdk =  new ESDK(new AwsEncryptionSdkConfig());
var mpl = new MaterialProviders(new MaterialProvidersConfig());
```

步骤 2：为密钥环创建输入对象。  
要为密钥环方法指定参数，请创建输入对象。for .NET 中的 AWS Encryption SDK 每个密钥环方法都有一个对应的输入对象。由于此示例使用 `CreateAwsKmsKeyring()` 方法创建密钥环，因此会为输入实例化 `CreateAwsKmsKeyringInput` 类。  
在解密密钥环中，您必须使用密钥 ARN 标识 KMS 密钥。  

```
string keyArn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";

// Instantiate the keyring input object
var kmsKeyringInput = new CreateAwsKmsKeyringInput
{
    KmsClient = new AmazonKeyManagementServiceClient(),
    KmsKeyId = keyArn
};
```

步骤 3：创建密钥环。  
要创建解密密钥环，此示例使用 `CreateAwsKmsKeyring()` 方法和密钥环输入对象。  

```
var keyring = materialProviders.CreateAwsKmsKeyring(kmsKeyringInput);
```

步骤 4：创建用于解密的输入对象。  
要为 `Decrypt()` 方法创建输入对象，请实例化 `DecryptInput` 类。  
`DecryptInput()` 构造函数的 `Ciphertext` 参数需要 `Encrypt()` 方法返回的 `EncryptOutput` 对象 `Ciphertext` 的成员。`Ciphertext` 属性表示[加密消息](concepts.md#message)，其中包括加密数据、加密数据密钥和 AWS Encryption SDK 解密消息所需元数据。  
使用版本 4。 *x* AWS Encryption SDK 对于.NET，您可以使用可选`EncryptionContext`参数在`Decrypt()`方法中指定您的加密上下文。  
使用 `EncryptionContext` 参数验证加密时使用的加密上下文*是否包含*在用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件（例如默认算法套件），则会将成对 AWS Encryption SDK 添加到加密上下文中，包括数字签名。  

```
var encryptedMessage = encryptOutput.Ciphertext;

var decryptInput = new DecryptInput
{
    Ciphertext = encryptedMessage,
    Keyring = keyring,
    EncryptionContext = encryptionContext // OPTIONAL
};
```

步骤 5：解密加密文字。  

```
var decryptOutput = encryptionSdk.Decrypt(decryptInput);
```

步骤 6：验证加密上下文 – 版本 3.*x*  
版本 3 `Decrypt()` 的方法。 .NET AWS Encryption SDK 的 *x* 不采用加密上下文。其会从加密消息的元数据中获取加密上下文值。但是，在返回或使用明文之前，最佳做法是验证用于解密加密文字的加密上下文是否包含您在加密时提供的加密上下文。  
验证加密时使用的加密上下文*是否包含*在用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件（例如默认算法套件），则会将成对 AWS Encryption SDK 添加到加密上下文中，包括数字签名。  

```
// Verify the encryption context
string contextKey = "purpose";
string contextValue = "test";

if (!decryptOutput.EncryptionContext.TryGetValue(contextKey, out var decryptContextValue)
    || !decryptContextValue.Equals(contextValue))
{
    throw new Exception("Encryption context does not match expected values");
}
```

## 在 for .NET 中使用发现密钥环进行解密 AWS Encryption SDK
<a name="dot-net-decrypt-discovery"></a>

您可以提供不指定任何 KMS 密钥的密钥环， AWS KMS *Discovery 密钥环*，而非指定用于解密的 KMS 密钥。发现 AWS Encryption SDK 密钥环允许使用任何加密数据的 KMS 密钥来解密数据，前提是调用者拥有密钥的解密权限。要获得最佳实践，请添加发现过滤器，将可用于特定分区的 KMS 密钥限制为特定 AWS 账户 分区的密钥。

fo AWS Encryption SDK r .NET 提供了一个基本的发现密钥环，它需要一个 AWS KMS 客户端，还有一个发现多密钥环，需要你指定一个或多个密钥环。 AWS 区域客户端和区域均限制可用于解密加密消息的 KMS 密钥。两个密钥环的输入对象均需要建议添加的发现筛选条件。

以下示例说明了使用 AWS KMS Discovery 密钥环和发现筛选条件解密数据的模式。

第 1 步：实例化材料提供者库 AWS Encryption SDK 和材料提供者库。  

```
// Instantiate the AWS Encryption SDK and material providers
var esdk =  new ESDK(new AwsEncryptionSdkConfig());
var mpl = new MaterialProviders(new MaterialProvidersConfig());
```

步骤 2：为密钥环创建输入对象。  
要为密钥环方法指定参数，请创建输入对象。for .NET 中的 AWS Encryption SDK 每个密钥环方法都有一个对应的输入对象。由于此示例使用 `CreateAwsKmsDiscoveryKeyring()` 方法创建密钥环，因此会为输入实例化 `CreateAwsKmsDiscoveryKeyringInput` 类。  

```
List<string> accounts = new List<string> { "111122223333" };

var discoveryKeyringInput = new CreateAwsKmsDiscoveryKeyringInput
{
    KmsClient = new AmazonKeyManagementServiceClient(),
    DiscoveryFilter = new DiscoveryFilter()
    {
        AccountIds = accounts,
        Partition = "aws"
    }
};
```

步骤 3：创建密钥环。  
要创建解密密钥环，此示例使用 `CreateAwsKmsDiscoveryKeyring()` 方法和密钥环输入对象。  

```
var discoveryKeyring = materialProviders.CreateAwsKmsDiscoveryKeyring(discoveryKeyringInput);
```

步骤 4：创建用于解密的输入对象。  
要为 `Decrypt()` 方法创建输入对象，请实例化 `DecryptInput` 类。`Ciphertext` 参数的值为 `Encrypt()` 方法返回的 `EncryptOutput` 对象的 `Ciphertext` 成员。  
使用版本 4。 *x* AWS Encryption SDK 对于.NET，您可以使用可选`EncryptionContext`参数在`Decrypt()`方法中指定您的加密上下文。  
使用 `EncryptionContext` 参数验证加密时使用的加密上下文*是否包含*在用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件（例如默认算法套件），则会将成对 AWS Encryption SDK 添加到加密上下文中，包括数字签名。  

```
var ciphertext = encryptOutput.Ciphertext;

var decryptInput = new DecryptInput
{
    Ciphertext = ciphertext,
    Keyring = discoveryKeyring,
    EncryptionContext = encryptionContext // OPTIONAL
    
};
var decryptOutput = encryptionSdk.Decrypt(decryptInput);
```

步骤 5：验证加密上下文 – 版本 3.*x*  
版本 3 `Decrypt()` 的方法。 .NET AWS Encryption SDK 的 *x* 不开启加密上下文`Decrypt()`。其会从加密消息的元数据中获取加密上下文值。但是，在返回或使用明文之前，最佳做法是验证用于解密加密文字的加密上下文是否包含您在加密时提供的加密上下文。  
验证加密时使用的加密上下文*是否包含*在曾用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件（例如默认算法套件），则会将成对 AWS Encryption SDK 添加到加密上下文中，包括数字签名。  

```
// Verify the encryption context
string contextKey = "purpose";
string contextValue = "test";

if (!decryptOutput.EncryptionContext.TryGetValue(contextKey, out var decryptContextValue)
    || !decryptContextValue.Equals(contextValue))
{
    throw new Exception("Encryption context does not match expected values");
}
```