Skip to content

Commit cae61dc

Browse files
commit'
1 parent e89a0fc commit cae61dc

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
This example configures a client with a specific commitment policy for the
5+
AWS Encryption SDK client, then encrypts and decrypts data using an AWS KMS Keyring.
6+
7+
The commitment policy in this example (FORBID_ENCRYPT_ALLOW_DECRYPT) should only be
8+
used as part of a migration from version 1.x to 2.x, or for advanced users with
9+
specialized requirements. Most AWS Encryption SDK users should use the default
10+
commitment policy (REQUIRE_ENCRYPT_REQUIRE_DECRYPT).
11+
12+
This example creates a KMS Keyring and then encrypts a custom input EXAMPLE_DATA
13+
with an encryption context for the commitment policy FORBID_ENCRYPT_ALLOW_DECRYPT.
14+
This example also includes some sanity checks for demonstration:
15+
1. Ciphertext and plaintext data are not the same
16+
2. Encryption context is correct in the decrypted message header
17+
3. Decrypted plaintext value matches EXAMPLE_DATA
18+
These sanity checks are for demonstration in the example only. You do not need these in your code.
19+
20+
For more information on setting your commitment policy, see
21+
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#commitment-policy
22+
"""
23+
import sys
24+
25+
import boto3
26+
from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
27+
from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
28+
from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsKeyringInput
29+
from aws_cryptographic_materialproviders.mpl.references import IKeyring
30+
from typing import Dict # noqa pylint: disable=wrong-import-order
31+
32+
import aws_encryption_sdk
33+
from aws_encryption_sdk import CommitmentPolicy
34+
35+
# TODO-MPL: Remove this as part of removing PYTHONPATH hacks.
36+
MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1])
37+
38+
sys.path.append(MODULE_ROOT_DIR)
39+
40+
EXAMPLE_DATA: bytes = b"Hello World"
41+
42+
43+
def encrypt_and_decrypt_with_keyring(
44+
kms_key_id: str
45+
):
46+
"""Demonstrate how to set your commitment policy for migration.
47+
48+
Usage: encrypt_and_decrypt_with_keyring(kms_key_id)
49+
:param kms_key_id: KMS Key identifier for the KMS key you want to use for encryption and
50+
decryption of your data keys.
51+
:type kms_key_id: string
52+
53+
For more information on KMS Key identifiers, see
54+
https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id
55+
"""
56+
# 1. Instantiate the encryption SDK client.
57+
# This example builds the client with the FORBID_ENCRYPT_ALLOW_DECRYPT commitment policy,
58+
# which enforces that this client cannot encrypt with key commitment
59+
# and it can decrypt ciphertexts encrypted with or without key commitment.
60+
# The default commitment policy if you were to build the client as
61+
# `client = aws_encryption_sdk.EncryptionSDKClient()` is REQUIRE_ENCRYPT_REQUIRE_DECRYPT.
62+
# We recommend that AWS Encryption SDK users use the default commitment policy
63+
# (REQUIRE_ENCRYPT_REQUIRE_DECRYPT) whenever possible.
64+
client = aws_encryption_sdk.EncryptionSDKClient(
65+
commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT
66+
)
67+
68+
# 2. Create a boto3 client for KMS.
69+
kms_client = boto3.client('kms', region_name="us-west-2")
70+
71+
# 3. Create encryption context.
72+
# Remember that your encryption context is NOT SECRET.
73+
# For more information, see
74+
# https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
75+
encryption_context: Dict[str, str] = {
76+
"encryption": "context",
77+
"is not": "secret",
78+
"but adds": "useful metadata",
79+
"that can help you": "be confident that",
80+
"the data you are handling": "is what you think it is",
81+
}
82+
83+
# 4. Create a KMS keyring
84+
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
85+
config=MaterialProvidersConfig()
86+
)
87+
88+
keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput(
89+
kms_key_id=kms_key_id,
90+
kms_client=kms_client
91+
)
92+
93+
kms_keyring: IKeyring = mat_prov.create_aws_kms_keyring(
94+
input=keyring_input
95+
)
96+
97+
# 5. Encrypt the data with the encryptionContext. Make sure you use a non-committing algorithm
98+
# with the commitment policy FORBID_ENCRYPT_ALLOW_DECRYPT. Otherwise client.encrypt() will throw
99+
# aws_encryption_sdk.exceptions.ActionNotAllowedError. By default for
100+
# FORBID_ENCRYPT_ALLOW_DECRYPT, the algorithm used is
101+
# AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 which is a non-committing algorithm.
102+
ciphertext, _ = client.encrypt(
103+
source=EXAMPLE_DATA,
104+
keyring=kms_keyring,
105+
encryption_context=encryption_context
106+
)
107+
108+
# 6. Demonstrate that the ciphertext and plaintext are different.
109+
# (This is an example for demonstration; you do not need to do this in your own code.)
110+
assert ciphertext != EXAMPLE_DATA, \
111+
"Ciphertext and plaintext data are the same. Invalid encryption"
112+
113+
# 7. Decrypt your encrypted data using the same keyring you used on encrypt.
114+
plaintext_bytes, dec_header = client.decrypt(
115+
source=ciphertext,
116+
keyring=kms_keyring
117+
)
118+
119+
# 8. Demonstrate that the encryption context is correct in the decrypted message header
120+
# (This is an example for demonstration; you do not need to do this in your own code.)
121+
for k, v in encryption_context.items():
122+
assert v == dec_header.encryption_context[k], \
123+
"Encryption context does not match expected values"
124+
125+
# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
126+
# (This is an example for demonstration; you do not need to do this in your own code.)
127+
assert plaintext_bytes == EXAMPLE_DATA, \
128+
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Test suite for the migration_set_commitment_policy_example."""
4+
import pytest
5+
6+
from ..src.migration_set_commitment_policy_example import encrypt_and_decrypt_with_keyring
7+
8+
pytestmark = [pytest.mark.examples]
9+
10+
11+
def test_encrypt_and_decrypt_with_keyring():
12+
"""Test function for setting commitment policy using the AWS KMS Keyring example."""
13+
kms_key_id = "arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f"
14+
encrypt_and_decrypt_with_keyring(kms_key_id)

0 commit comments

Comments
 (0)