Key commitment assures that your encrypted data always decrypts to the same plaintext. To provide this security property, beginning in version 1.7.x, the AWS Encryption SDK uses new algorithm suites with key commitment. To determine whether your data is encrypted and decrypted with key commitment, use the commitment policy configuration setting. Encrypting and decrypting data with key commitment is an AWS Encryption SDK best practice.
Setting a commitment policy is an important part of the second step in the migration process â migrating from the latest 1.x versions of the AWS Encryption SDK to versions 2.0.x and later. After setting and changing your commitment policy, be sure to test your application thoroughly before deploying it in production. For migration guidance, see How to migrate and deploy the AWS Encryption SDK.
The commitment policy setting has three valid values in versions 2.0.x and later. In the latest 1.x versions (beginning with version 1.7.x), only ForbidEncryptAllowDecrypt
is valid.
ForbidEncryptAllowDecrypt
â The AWS Encryption SDK cannot encrypt with key commitment. It can decrypt ciphertexts encrypted with or without key commitment.
In the latest 1.x versions, this is the only valid value. It ensures that you don't encrypt with key commitment until you are fully prepared to decrypt with key commitment. Setting the value explicitly prevents your commitment policy from changing automatically to require-encrypt-require-decrypt
when you upgrade to versions 2.0.x or later. Instead, you can migrate your commitment policy in stages.
RequireEncryptAllowDecrypt
â The AWS Encryption SDK always encrypts with key commitment. It can decrypt ciphertexts encrypted with or without key commitment. This value is added in version 2.0.x.
RequireEncryptRequireDecrypt
â The AWS Encryption SDK always encrypts and decrypts with key commitment. This value is added in version 2.0.x. It is the default value in versions 2.0.x and later.
In the latest 1.x versions, the only valid commitment policy value is ForbidEncryptAllowDecrypt
. After you migrate to version 2.0.x or later, you can change your commitment policy in stages as you are ready. Don't update your commitment policy to RequireEncryptRequireDecrypt
until you are certain that you don't have any messages encrypted without key commitment.
These examples show you how to set your commitment policy in the latest 1.x versions and in versions 2.0.x and later. The technique depends on your programming language.
Learn more about migration
For AWS Encryption SDK for Java, AWS Encryption SDK for Python, and the AWS Encryption CLI, learn about required changes to master key providers in Updating AWS KMS master key providers.
For AWS Encryption SDK for C and AWS Encryption SDK for JavaScript, learn about an optional update to keyrings in Updating AWS KMS keyrings.
How to set your commitment policyThe technique that you use to set your commitment policy differs slightly with each language implementation. These examples show you how to do it. Before changing your commitment policy, review the multi-stage approach in How to migrate and deploy.
Beginning in version 1.7.x of the AWS Encryption SDK for C, you use the aws_cryptosdk_session_set_commitment_policy
function to set the commitment policy on your encrypt and decrypt sessions. The commitment policy that you set applies to all encrypt and decrypt operations called on that session.
The aws_cryptosdk_session_new_from_keyring
and aws_cryptosdk_session_new_from_cmm
functions are deprecated in version 1.7.x and removed in version 2.0.x. These functions are replaced by aws_cryptosdk_session_new_from_keyring_2
and aws_cryptosdk_session_new_from_cmm_2
functions that return a session.
When you use the aws_cryptosdk_session_new_from_keyring_2
and aws_cryptosdk_session_new_from_cmm_2
in the latest 1.x versions, you are required to call the aws_cryptosdk_session_set_commitment_policy
function with the COMMITMENT_POLICY_FORBID_ENCRYPT_ALLOW_DECRYPT
commitment policy value. In versions 2.0.x and later, calling this function is optional and it takes all valid values. The default commitment policy for versions 2.0.x and later is COMMITMENT_POLICY_REQUIRE_ENCRYPT_REQUIRE_DECRYPT
.
For a complete example, see string.cpp.
/* Load error strings for debugging */
aws_cryptosdk_load_error_strings();
/* Create an AWS KMS keyring */
const char * key_arn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
";
struct aws_cryptosdk_keyring *kms_keyring = Aws::Cryptosdk::KmsKeyring::Builder().Build(key_arn);
/* Create an encrypt session with a CommitmentPolicy setting */
struct aws_cryptosdk_session *encrypt_session = aws_cryptosdk_session_new_from_keyring_2(
alloc, AWS_CRYPTOSDK_ENCRYPT, kms_keyring);
aws_cryptosdk_keyring_release(kms_keyring);
aws_cryptosdk_session_set_commitment_policy(encrypt_session,
COMMITMENT_POLICY_FORBID_ENCRYPT_ALLOW_DECRYPT);
...
/* Encrypt your data */
size_t plaintext_consumed_output;
aws_cryptosdk_session_process(encrypt_session,
ciphertext_output,
ciphertext_buf_sz_output,
ciphertext_len_output,
plaintext_input,
plaintext_len_input,
&plaintext_consumed_output)
...
/* Create a decrypt session with a CommitmentPolicy setting */
struct aws_cryptosdk_keyring *kms_keyring = Aws::Cryptosdk::KmsKeyring::Builder().Build(key_arn);
struct aws_cryptosdk_session *decrypt_session = *aws_cryptosdk_session_new_from_keyring_2(
alloc, AWS_CRYPTOSDK_DECRYPT, kms_keyring);
aws_cryptosdk_keyring_release(kms_keyring);
aws_cryptosdk_session_set_commitment_policy(decrypt_session,
COMMITMENT_POLICY_FORBID_ENCRYPT_ALLOW_DECRYPT);
/* Decrypt your ciphertext */
size_t ciphertext_consumed_output;
aws_cryptosdk_session_process(decrypt_session,
plaintext_output,
plaintext_buf_sz_output,
plaintext_len_output,
ciphertext_input,
ciphertext_len_input,
&ciphertext_consumed_output)
The require-encrypt-require-decrypt
value is the default commitment policy in all versions of the AWS Encryption SDK for .NET. You can set it explicitly as a best practice, but it's not required. However, if you are using the AWS Encryption SDK for .NET to decrypt ciphertext that was encrypted by another language implementation of the AWS Encryption SDK without key commitment, you need to change the commitment policy value to REQUIRE_ENCRYPT_ALLOW_DECRYPT
or FORBID_ENCRYPT_ALLOW_DECRYPT
. Otherwise, attempts to decrypt the ciphertext will fail.
In the AWS Encryption SDK for .NET, you set the commitment policy on an instance of the AWS Encryption SDK. Instantiate an AwsEncryptionSdkConfig
object with a CommitmentPolicy
parameter, and use the configuration object to create the AWS Encryption SDK instance. Then, call the Encrypt()
and Decrypt()
methods of the configured AWS Encryption SDK instance.
This example sets the commitment policy to require-encrypt-allow-decrypt
.
// Instantiate the material providers
var materialProviders =
AwsCryptographicMaterialProvidersFactory.CreateDefaultAwsCryptographicMaterialProviders();
// Configure the commitment policy on the AWS Encryption SDK instance
var config = new AwsEncryptionSdkConfig
{
CommitmentPolicy = CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT
};
var encryptionSdk = AwsEncryptionSdkFactory.CreateAwsEncryptionSdk(config);
string keyArn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
";
var encryptionContext = new Dictionary<string, string>()
{
{"purpose", "test"}encryptionSdk
};
var createKeyringInput = new CreateAwsKmsKeyringInput
{
KmsClient = new AmazonKeyManagementServiceClient(),
KmsKeyId = keyArn
};
var keyring = materialProviders.CreateAwsKmsKeyring(createKeyringInput);
// Encrypt your plaintext data
var encryptInput = new EncryptInput
{
Plaintext = plaintext,
Keyring = keyring,
EncryptionContext = encryptionContext
};
var encryptOutput = encryptionSdk.Encrypt(encryptInput);
// Decrypt your ciphertext
var decryptInput = new DecryptInput
{
Ciphertext = ciphertext,
Keyring = keyring
};
var decryptOutput = encryptionSdk.Decrypt(decryptInput);
To set a commitment policy in the AWS Encryption CLI, use the --commitment-policy
parameter. This parameter is introduced in version 1.8.x.
In the latest 1.x version, when you use the --wrapping-keys
parameter in an --encrypt
or --decrypt
command, a --commitment-policy
parameter with the forbid-encrypt-allow-decrypt
value is required. Otherwise, the --commitment-policy
parameter is invalid.
In versions 2.1.x and later, the --commitment-policy
parameter is optional and defaults to the require-encrypt-require-decrypt
value, which won't encrypt or decrypt any ciphertext encrypted without key commitment. However, we recommend that you set the commitment policy explicitly in all encrypt and decrypt calls to help with maintenance and troubleshooting.
This example sets the commitment policy. It also uses the --wrapping-keys
parameter that replaces the --master-keys
parameter beginning in version 1.8.x. For details, see Updating AWS KMS master key providers. For complete examples, see Examples of the AWS Encryption CLI.
\\ To run this example, replace the fictitious key ARN with a valid value.
$ keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
\\ Encrypt your plaintext data - no change to algorithm suite used
$ aws-encryption-cli --encrypt \
--input hello.txt \
--wrapping-keys key=$keyArn \
--commitment-policy forbid-encrypt-allow-decrypt \
--metadata-output ~/metadata \
--encryption-context purpose=test \
--output .
\\ Decrypt your ciphertext - supports key commitment on 1.7 and later
$ aws-encryption-cli --decrypt \
--input hello.txt.encrypted \
--wrapping-keys key=$keyArn \
--commitment-policy forbid-encrypt-allow-decrypt \
--encryption-context purpose=test \
--metadata-output ~/metadata \
--output .
Beginning in version 1.7.x of the AWS Encryption SDK for Java, you set the commitment policy on your instance of AwsCrypto
, the object that represents the AWS Encryption SDK client. This commitment policy setting applies to all encrypt and decrypt operations called on that client.
The AwsCrypto()
constructor is deprecated in the latest 1.x versions of the AWS Encryption SDK for Java and is removed in version 2.0.x. It's replaced by a new Builder
class, a Builder.withCommitmentPolicy()
method, and the CommitmentPolicy
enumerated type.
In the latest 1.x versions, the Builder
class requires the Builder.withCommitmentPolicy()
method and the CommitmentPolicy.ForbidEncryptAllowDecrypt
argument. Beginning in version 2.0.x, the Builder.withCommitmentPolicy()
method is optional; the default value is CommitmentPolicy.RequireEncryptRequireDecrypt
.
For a complete example, see SetCommitmentPolicyExample.java.
// Instantiate the client
final AwsCrypto crypto = AwsCrypto.builder()
.withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt)
.build();
// Create a master key provider in strict mode
String awsKmsKey = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
";
KmsMasterKeyProvider masterKeyProvider = KmsMasterKeyProvider.builder()
.buildStrict(awsKmsKey);
// Encrypt your plaintext data
CryptoResult<byte[], KmsMasterKey> encryptResult = crypto.encryptData(
masterKeyProvider,
sourcePlaintext,
encryptionContext);
byte[] ciphertext = encryptResult.getResult();
// Decrypt your ciphertext
CryptoResult<byte[], KmsMasterKey> decryptResult = crypto.decryptData(
masterKeyProvider,
ciphertext);
byte[] decrypted = decryptResult.getResult();
Beginning in version 1.7.x of the AWS Encryption SDK for JavaScript, you can set the commitment policy when you call the new buildClient
function that instantiates an AWS Encryption SDK client. The buildClient
function takes an enumerated value that represents your commitment policy. It returns updated encrypt
and decrypt
functions that enforce your commitment policy when you encrypt and decrypt.
In the latest 1.x versions, the buildClient
function requires the CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT
argument. Beginning in version 2.0.x, the commitment policy argument is optional and the default value is CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
.
The code for Node.js and the browser are identical for this purpose, except that browser needs a statement to set credentials.
The following example encrypts data with an AWS KMS keyring. The new buildClient
function sets the commitment policy to FORBID_ENCRYPT_ALLOW_DECRYPT
, the default value in the latest 1.x versins. The upgraded encrypt
and decrypt
functions that buildClient
returns enforce the commitment policy you set.
import { buildClient } from '@aws-crypto/client-node'
const { encrypt, decrypt } = buildClient(CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT)
// Create an AWS KMS keyring
const generatorKeyId = 'arn:aws:kms:us-west-2:111122223333:alias/ExampleAlias
'
const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
']
const keyring = new KmsKeyringNode({ generatorKeyId, keyIds })
// Encrypt your plaintext data
const { ciphertext } = await encrypt(keyring, plaintext, { encryptionContext: context })
// Decrypt your ciphertext
const { decrypted, messageHeader } = await decrypt(keyring, ciphertext)
Beginning in version 1.7.x of the AWS Encryption SDK for Python, you set the commitment policy on your instance of EncryptionSDKClient
, a new object that represents the AWS Encryption SDK client. The commitment policy that you set applies to all encrypt
and decrypt
calls that use that instance of the client.
In the latest 1.x versions, the EncryptionSDKClient
constructor requires the CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT
enumerated value. Beginning in version 2.0.x, the commitment policy argument is optional and the default value is CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
.
This example uses the new EncryptionSDKClient
constructor and sets the commitment policy to the 1.7.x default value. The constructor instantiates a client that represents the AWS Encryption SDK. When you call the encrypt
, decrypt
, or stream
methods on this client, they enforce the commitment policy that you set. This example also uses the new constructor for the StrictAwsKmsMasterKeyProvider
class, which specifies AWS KMS keys when encrypting and decrypting.
For a complete example, see set_commitment.py.
# Instantiate the client
client = aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT)
// Create a master key provider in strict mode
aws_kms_key = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
"
aws_kms_strict_master_key_provider = StrictAwsKmsMasterKeyProvider(
key_ids=[aws_kms_key]
)
# Encrypt your plaintext data
ciphertext, encrypt_header = client.encrypt(
source=source_plaintext,
encryption_context=encryption_context,
master_key_provider=aws_kms_strict_master_key_provider
)
# Decrypt your ciphertext
decrypted, decrypt_header = client.decrypt(
source=ciphertext,
master_key_provider=aws_kms_strict_master_key_provider
)
The require-encrypt-require-decrypt
value is the default commitment policy in all versions of the AWS Encryption SDK for Rust. You can set it explicitly as a best practice, but it's not required. However, if you are using the AWS Encryption SDK for Rust to decrypt ciphertext that was encrypted by another language implementation of the AWS Encryption SDK without key commitment, you need to change the commitment policy value to REQUIRE_ENCRYPT_ALLOW_DECRYPT
or FORBID_ENCRYPT_ALLOW_DECRYPT
. Otherwise, attempts to decrypt the ciphertext will fail.
In the AWS Encryption SDK for Rust, you set the commitment policy on an instance of the AWS Encryption SDK. Instantiate an AwsEncryptionSdkConfig
object with a comitment_policy
parameter, and use the configuration object to create the AWS Encryption SDK instance. Then, call the Encrypt()
and Decrypt()
methods of the configured AWS Encryption SDK instance.
This example sets the commitment policy to forbid-encrypt-allow-decrypt
.
// Configure the commitment policy on the AWS Encryption SDK instance
let esdk_config = AwsEncryptionSdkConfig::builder()
.commitment_policy(ForbidEncryptAllowDecrypt)
.build()?;
let esdk_client = esdk_client::Client::from_conf(esdk_config)?;
// Create an AWS KMS client
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let kms_client = aws_sdk_kms::Client::new(&sdk_config);
// Create your encryption context
let encryption_context = HashMap::from([
("encryption".to_string(), "context".to_string()),
("is not".to_string(), "secret".to_string()),
("but adds".to_string(), "useful metadata".to_string()),
("that can help you".to_string(), "be confident that".to_string()),
("the data you are handling".to_string(), "is what you think it is".to_string()),
]);
// Instantiate the material providers library
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;
// Create an AWS KMS keyring
let kms_keyring = mpl
.create_aws_kms_keyring()
.kms_key_id(kms_key_id)
.kms_client(kms_client)
.send()
.await?;
// Encrypt your plaintext data
let plaintext = example_data.as_bytes();
let encryption_response = esdk_client.encrypt()
.plaintext(plaintext)
.keyring(kms_keyring.clone())
.encryption_context(encryption_context.clone())
.send()
.await?;
// Decrypt your ciphertext
let decryption_response = esdk_client.decrypt()
.ciphertext(ciphertext)
.keyring(kms_keyring)
// Provide the encryption context that was supplied to the encrypt method
.encryption_context(encryption_context)
.send()
.await?;
import (
"context"
mpl "aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygenerated"
mpltypes "aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygeneratedtypes"
client "github.com/aws/aws-encryption-sdk/awscryptographyencryptionsdksmithygenerated"
esdktypes "github.com/aws/aws-encryption-sdk/awscryptographyencryptionsdksmithygeneratedtypes"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/kms"
)
// Instantiate the AWS Encryption SDK client
commitPolicyForbidEncryptAllowDecrypt := mpltypes.ESDKCommitmentPolicyForbidEncryptAllowDecrypt
encryptionClient, err := client.NewClient(esdktypes.AwsEncryptionSdkConfig{CommitmentPolicy: &commitPolicyForbidEncryptAllowDecrypt})
if err != nil {
panic(err)
}
// Create an AWS KMS client
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
panic(err)
}
kmsClient := kms.NewFromConfig(cfg, func(o *kms.Options) {
o.Region = KmsKeyRegion
})
// Optional: Create an encryption context
encryptionContext := map[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 material providers library
matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{})
if err != nil {
panic(err)
}
// Create an AWS KMS keyring
awsKmsKeyringInput := mpltypes.CreateAwsKmsKeyringInput{
KmsClient: kmsClient,
KmsKeyId: kmsKeyId,
}
awsKmsKeyring, err := matProv.CreateAwsKmsKeyring(context.Background(), awsKmsKeyringInput)
if err != nil {
panic(err)
}
// Encrypt your plaintext data
res, err := forbidEncryptClient.Encrypt(context.Background(), esdktypes.EncryptInput{
Plaintext: []byte(exampleText),
EncryptionContext: encryptionContext,
Keyring: awsKmsKeyring,
})
if err != nil {
panic(err)
}
// Decrypt your ciphertext
decryptOutput, err := forbidEncryptClient.Decrypt(context.Background(), esdktypes.DecryptInput{
Ciphertext: res.Ciphertext,
EncryptionContext: encryptionContext,
Keyring: awsKmsKeyring,
})
if err != nil {
panic(err)
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4