适用于 .NET 的 AWS Encryption SDK 示例 - AWS Encryption SDK

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

适用于 .NET 的 AWS Encryption SDK 示例

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

有关说明如何在 AWS Encryption SDK 中配置选项(例如指定备用算法套件、限制加密数据密钥和使用 AWS KMS 多区域密钥)的示例,请参阅 正在配置 AWS Encryption SDK

有关使用适用于 .NET 的 AWS Encryption SDK 进行编程的更多示例,请参阅 GitHub aws-encryption-sdk-dafny 存储库 aws-encryption-sdk-net 目录中的示例

加密适用于 .NET 的 AWS Encryption SDK 中的数据

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

步骤 1:实例化 AWS Encryption SDK 和材料提供程序库。

首先实例化 AWS Encryption SDK 和材料提供程序库。您将使用 AWS Encryption SDK 中的方法加密和解密数据。您将使用材料提供程序库中的方法创建密钥环,密钥环指定哪些密钥保护您的数据。

在适用于 .NET 的 AWS Encryption SDK 版本 3.x 和 4.x 中,AWS Encryption SDK 和材料提供程序库的实例化方式有所不同。适用于 .NET 的 AWS Encryption SDK 版本 3.x 和 4.x 的以下所有步骤相同。

Version 3.x
// Instantiate the AWS Encryption SDK and material providers var encryptionSdk = AwsEncryptionSdkFactory.CreateDefaultAwsEncryptionSdk(); var materialProviders = AwsCryptographicMaterialProvidersFactory.CreateDefaultAwsCryptographicMaterialProviders();
Version 4.x
// Instantiate the AWS Encryption SDK and material providers var esdk = new ESDK(new AwsEncryptionSdkConfig()); var mpl = new MaterialProviders(new MaterialProvidersConfig());
步骤 2:为密钥环创建输入对象。

每个密钥环创建方法均有对应的输入对象类。例如,要为 CreateAwsKmsKeyring() 方法创建输入对象,请创建 CreateAwsKmsKeyringInput 类的实例。

尽管此密钥环的输入未指定生成器密钥,但 KmsKeyId 参数指定的单个 KMS 密钥即为生成器密钥。其生成并加密进行数据加密的数据密钥。

此输入对象需要适用于 KMS 密钥 AWS 区域 的 AWS KMS 客户端。要创建 AWS KMS 客户端,请在 AWS SDK for .NET 中实例化 AmazonKeyManagementServiceClient 类。调用不带参数的 AmazonKeyManagementServiceClient() 构造函数会创建具有默认值的客户端。

在对适用于 .NET 的 AWS Encryption SDK 进行加密的 AWS KMS 密钥环中,您可以使用密钥 ID、密钥 ARN、别名名称或别名 ARN 来标识 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:定义加密上下文。

加密上下文是 AWS Encryption SDK 加密操作中的一个可选但强烈建议使用的元素。您可以定义一个或多个非机密键值对。

注意

借助适用于 .NET 的 AWS Encryption SDK 版本 4.x,您可以使用必需的加密上下文 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:加密明文。

按照 AWS Encryption SDK 的 Encrypt() 方法,使用您定义的密钥环加密明文。

Encrypt() 方法返回的 EncryptOutput 包含用于获取加密消息 (Ciphertext)、加密上下文和算法套件的方法。

var encryptOutput = encryptionSdk.Encrypt(encryptInput);
步骤 7:获取加密消息。

适用于 .NET 的 AWS Encryption SDK 中的 Decrypt() 方法采用 EncryptOutput 实例的 Ciphertext 成员。

EncryptOutput 对象的 Ciphertext 成员是加密消息,其为便携式对象,其中包括加密数据、加密数据密钥和元数据,包括加密上下文。您可以长时间安全存储加密消息,也可以将其提交给 Decrypt() 方法以便恢复明文。

var encryptedMessage = encryptOutput.Ciphertext;

在适用于 .NET 的 AWS Encryption SDK 中在严格模式下解密

最佳实践建议您指定用于解密数据的密钥,该选项称为严格模式。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:为密钥环创建输入对象。

要为密钥环方法指定参数,请创建输入对象。适用于 .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 属性表示加密消息,其中包括加密数据、加密数据密钥和 AWS Encryption SDK 解密消息所需元数据。

借助适用于 .NET 的 AWS Encryption SDK 版本 4.x,您可以使用可选 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

适用于 .NET 的 AWS Encryption SDK 版本 3.xDecrypt() 方法不需要加密上下文。其会从加密消息的元数据中获取加密上下文值。但是,在返回或使用明文之前,最佳做法是验证用于解密加密文字的加密上下文是否包含您在加密时提供的加密上下文。

验证加密时使用的加密上下文是否包含在用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件(例如默认算法套件),则 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"); }

使用适用于 .NET 的 AWS Encryption SDK 中的 Discovery 密钥环进行解密

您可以提供不指定任何 KMS 密钥的密钥环,AWS KMS Discovery 密钥环,而非指定用于解密的 KMS 密钥。Discovery 密钥环允许 AWS Encryption SDK 使用任何对其进行加密的 KMS 密钥来解密数据,但调用方必须拥有密钥的解密权限。作为最佳实践,请添加发现筛选条件,将可使用的 KMS 密钥限制为指定分区特定 AWS 账户 的密钥。

适用于 .NET 的 AWS Encryption SDK 提供了一个基本的 Discovery 密钥环,其需要一个 AWS KMS 客户端;还有一个 Discovery 多重密钥环,需要您指定一个或多个 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:为密钥环创建输入对象。

要为密钥环方法指定参数,请创建输入对象。适用于 .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 成员。

借助适用于 .NET 的 AWS Encryption SDK 版本 4.x,您可以使用可选 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

适用于 .NET 的 AWS Encryption SDK 版本 3.xDecrypt() 方法 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"); }