AWS Encryption SDK for .NET - AWS Encryption SDK

AWS Encryption SDK for .NET

The AWS Encryption SDK for .NET is a client-side encryption library for developers who are writing applications in C# and other .NET programming languages. It is supported on Windows, macOS, and Linux.

All programming language implementations of the AWS Encryption SDK are fully interoperable. However, if you encrypt data using the required encryption context CMM in version 4.x of the AWS Encryption SDK for .NET, you can only decrypt it with version 4.x of the AWS Encryption SDK for .NET or version 3.x of the AWS Encryption SDK for Java.

Note

Version 4.0.0 of the AWS Encryption SDK for .NET deviates from the AWS Encryption SDK Message Specification. As a result, messages encrypted by version 4.0.0 can only be decrypted by version 4.0.0 or later of the AWS Encryption SDK for .NET. They cannot be decrypted by any other programming language implementation.

Version 4.0.1 of the AWS Encryption SDK for .NET writes messages according to the AWS Encryption SDK Message Specification, and is interoperable with other programming language implementations. By default, version 4.0.1 can read messages encrypted by version 4.0.0. However, if you do not want to decrypt messages encrypted by version 4.0.0, you can specify the NetV4_0_0_RetryPolicy property to prevent the client from reading these messages. For more information, see the v4.0.1 release notes in the aws-encryption-sdk-dafny repository on GitHub.

The AWS Encryption SDK for .NET differs from some of the other programming language implementations of the AWS Encryption SDK in the following ways:

The AWS Encryption SDK for .NET includes all of the security features introduced in versions 2.0.x and later of other language implementations of the AWS Encryption SDK. However, if you are using the AWS Encryption SDK for .NET to decrypt data that was encrypted by a pre-2.0.x version another language implementation of the AWS Encryption SDK, you might need to adjust your commitment policy. For details, see How to set your commitment policy.

The AWS Encryption SDK for .NET is a product of the AWS Encryption SDK in Dafny, a formal verification language in which you write specifications, the code to implement them, and the proofs to test them. The result is a library that implements the features of the AWS Encryption SDK in a framework that assures functional correctness.

Learn More

  • For examples showing how to configure options in the AWS Encryption SDK, such as specifying an alternate algorithm suite, limiting encrypted data keys, and using AWS KMS multi-Region keys, see Configuring the AWS Encryption SDK.

  • For details about programming with the AWS Encryption SDK for .NET, see the aws-encryption-sdk-net directory of the aws-encryption-sdk-dafny repository on GitHub.

Installing the AWS Encryption SDK for .NET

The AWS Encryption SDK for .NET is available as the AWS.Cryptography.EncryptionSDK package in NuGet. For details about installing and building the AWS Encryption SDK for .NET, see the README.md file in the aws-encryption-sdk-net repository.

Version 3.x

Version 3.x of the AWS Encryption SDK for .NET supports .NET Framework 4.5.2 – 4.8 only on Windows. It supports .NET Core 3.0+ and .NET 5.0 and later on all supported operating systems.

Version 4.x

Version 4.x of the AWS Encryption SDK for .NET supports .NET 6.0 and .NET Framework net48 and later.

The AWS Encryption SDK for .NET requires the AWS SDK for .NET even if you aren't using AWS Key Management Service (AWS KMS) keys. It's installed with the NuGet package. However, unless you are using AWS KMS keys, AWS Encryption SDK for .NET does not require an AWS account, AWS credentials, or interaction with any AWS service. For help setting up an AWS account if you need it, see Using the AWS Encryption SDK with AWS KMS.

Debugging the AWS Encryption SDK for .NET

The AWS Encryption SDK for .NET does not generate any logs. Exceptions in the AWS Encryption SDK for .NET generate an exception message, but no stack traces.

To help you debug, be sure to enable logging in the AWS SDK for .NET. The logs and error messages from the AWS SDK for .NET can help you distinguish errors arising in the AWS SDK for .NET from those in the AWS Encryption SDK for .NET. For help with AWS SDK for .NET logging, see AWSLogging in the AWS SDK for .NET Developer Guide. (To see the topic, expand the Open to view .NET Framework content section.)

AWS KMS keyrings in the AWS Encryption SDK for .NET

The basic AWS KMS keyrings in the AWS Encryption SDK for .NET take only one KMS key. They also require an AWS KMS client, which gives you an opportunity to configure the client for the AWS Region of the KMS key.

To create a AWS KMS keyring with one or more wrapping keys, use a multi-keyring. The AWS Encryption SDK for .NET has a special multi-keyring that takes one or more AWS KMS keys, and a standard multi-keyring that takes one or more keyrings of any supported type. Some programmers prefer to use a multi-keyring method to create all of their keyrings, and the AWS Encryption SDK for .NET supports that strategy.

The AWS Encryption SDK for .NET provides basic single-key keyrings and multi-keyrings for all typical use-cases, including AWS KMS multi-Region keys.

For example, to create a AWS KMS keyring with one AWS KMS key, you can use the CreateAwsKmsKeyring() method.

Version 3.x

The following example uses version 3.x of the AWS Encryption SDK for .NET to create a default AWS KMS client for the Region that contains the specified key.

// Instantiate the AWS Encryption SDK and material providers var encryptionSdk = AwsEncryptionSdkFactory.CreateDefaultAwsEncryptionSdk(); var materialProviders = AwsCryptographicMaterialProvidersFactory.CreateDefaultAwsCryptographicMaterialProviders(); 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 }; // Create the keyring var keyring = materialProviders.CreateAwsKmsKeyring(kmsKeyringInput);
Version 4.x

The following example uses version 4.x of the AWS Encryption SDK for .NET to create an AWS KMS client for the Region that contains the specified key.

// Instantiate the AWS Encryption SDK and material providers var esdk = new ESDK(new AwsEncryptionSdkConfig()); var mpl = new MaterialProviders(new MaterialProvidersConfig()); string keyArn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; // Instantiate the keyring input object var createKeyringInput = new CreateAwsKmsKeyringInput { KmsClient = new AmazonKeyManagementServiceClient(), KmsKeyId = kmsArn }; // Create the keyring var kmsKeyring = mpl.CreateAwsKmsKeyring(createKeyringInput);

To create a keyring with one or more AWS KMS keys, use the CreateAwsKmsMultiKeyring() method. This example uses two AWS KMS keys. To specify one KMS key, use only the Generator parameter. The KmsKeyIds parameter that specifies additional KMS keys is optional.

The input for this keyring doesn't take an AWS KMS client. Instead, the AWS Encryption SDK uses the default AWS KMS client for each Region represented by a KMS key in the keyring. For example, if the KMS key identified by the value of the Generator parameter is in the US West (Oregon) Region (us-west-2), the AWS Encryption SDK creates a default AWS KMS client for the us-west-2 Region. If you need to customize the AWS KMS client, use the CreateAwsKmsKeyring() method.

The following example uses version 4.x of the AWS Encryption SDK for .NET and the CreateAwsKmsKeyring() method to customize the AWS KMS client.

// Instantiate the AWS Encryption SDK and material providers var esdk = new ESDK(new AwsEncryptionSdkConfig()); var mpl = new MaterialProviders(new MaterialProvidersConfig()); string generatorKey = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; List<string> additionalKeys = new List<string> { "arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321" }; // Instantiate the keyring input object var createEncryptKeyringInput = new CreateAwsKmsMultiKeyringInput { Generator = generatorKey, KmsKeyIds = additionalKeys }; var kmsEncryptKeyring = materialProviders.CreateAwsKmsMultiKeyring(createEncryptKeyringInput);

Version 4.x of the AWS Encryption SDK for .NET supports AWS KMS keyrings that use symmetric encryption (SYMMETRIC_DEFAULT) or asymmetric RSA KMS keys. AWS KMS keyrings created with asymmetric RSA KMS keys can only contain one key pair.

To encrypt with an asymmetric RSA AWS KMS keyring, you do not need kms:GenerateDataKey or kms:Encrypt because you must specify the public key material that you want to use for encryption when you create the keyring. No AWS KMS calls are made when encrypting with this keyring. To decrypt with an asymmetric RSA AWS KMS keyring, you need kms:Decrypt permission.

To create an asymmetric RSA AWS KMS keyring, you must provide the public key and private key ARN from your asymmetric RSA KMS key. The public key must be PEM encoded. The following example creates an AWS KMS keyring with an asymmetric RSA key pair.

// Instantiate the AWS Encryption SDK and material providers var esdk = new ESDK(new AwsEncryptionSdkConfig()); var mpl = new MaterialProviders(new MaterialProvidersConfig()); var publicKey = new MemoryStream(Encoding.UTF8.GetBytes(AWS KMS RSA public key)); // Instantiate the keyring input object var createKeyringInput = new CreateAwsKmsRsaKeyringInput { KmsClient = new AmazonKeyManagementServiceClient(), KmsKeyId = AWS KMS RSA private key ARN, PublicKey = publicKey, EncryptionAlgorithm = EncryptionAlgorithmSpec.RSAES_OAEP_SHA_256 }; // Create the keyring var kmsRsaKeyring = mpl.CreateAwsKmsRsaKeyring(createKeyringInput);

Required encryption contexts in version 4.x

With version 4.x of the AWS Encryption SDK for .NET, you can use the required encryption context CMM to require encryption contexts in your cryptographic operations. An encryption context is a set of non-secret key–value pairs. The encryption context is cryptographically bound to the encrypted data so that the same encryption context is required to decrypt the field. When you use the required encryption context CMM, you can specify one or more required encryption context keys (required keys) that must be included in all encrypt and decrypt calls.

Note

The required encryption context CMM is only interoperable with version 3.x of the AWS Encryption SDK for Java. It is not interoperable with any other programming language implementation. If you encrypt data using the required encryption context CMM, you can only decrypt it with version 3.x of the AWS Encryption SDK for Java or version 4.x of the AWS Encryption SDK for .NET.

On encrypt, the AWS Encryption SDK verifies that all required encryption context keys are included in the encryption context that you specified. The AWS Encryption SDK signs the encryption contexts that you specified. Only the key-value pairs that are not required keys are serialized and stored in plaintext in the header of the encrypted message that the encrypt operation returns.

On decrypt, you must provide an encryption context that contains all of the key-value pairs that represent the required keys. The AWS Encryption SDK uses this encryption context and the key-value pairs stored in the encrypted message’s header to reconstruct the original encryption context that you specified in the encrypt operation. If the AWS Encryption SDK cannot reconstruct the original encryption context, then the decrypt operation fails. If you provide a key-value pair that contains the required key with an incorrect value, the encrypted message cannot be decrypted. You must provide the same key-value pair that was specified on encrypt.

Important

Carefully consider which values you choose for the required keys in your encryption context. You must be able to provide the same keys and their corresponding values again on decrypt. If you're unable to reproduce the required keys, the encrypted message cannot be decrypted.

The following example initializes an AWS KMS keyring with the required encryption context CMM.

var encryptionContext = new Dictionary<string, string>() { {"encryption", "context"}, {"is not", "secret"}, {"but adds", "useful metadata"}, {"that can help you", "be confident that"}, {"the data you are handling", "is what you think it is"} }; // Instantiate the AWS Encryption SDK and material providers var esdk = new ESDK(new AwsEncryptionSdkConfig()); var mpl = new MaterialProviders(new MaterialProvidersConfig()); // Instantiate the keyring input object var createKeyringInput = new CreateAwsKmsKeyringInput { KmsClient = new AmazonKeyManagementServiceClient(), KmsKeyId = kmsKey }; // Create the keyring var kmsKeyring = mpl.CreateAwsKmsKeyring(createKeyringInput); var createCMMInput = new CreateRequiredEncryptionContextCMMInput { UnderlyingCMM = mpl.CreateDefaultCryptographicMaterialsManager(new CreateDefaultCryptographicMaterialsManagerInput{Keyring = kmsKeyring}), // If you pass in a keyring but no underlying cmm, it will result in a failure because only cmm is supported. RequiredEncryptionContextKeys = new List<string>(encryptionContext.Keys) }; // Create the required encryption context CMM var requiredEcCMM = mpl.CreateRequiredEncryptionContextCMM(createCMMInput);

If you use an AWS KMS keyring, the AWS Encryption SDK for .NET also uses the encryption context to provide additional authenticated data (AAD) in the calls the keyring makes to AWS KMS.