8000 docs: add KMS MK/P examples · aws/aws-encryption-sdk-python@d6b86c7 · GitHub
[go: up one dir, main page]

Skip to content

Commit d6b86c7

Browse files
committed
docs: add KMS MK/P examples
1 parent 97c60ba commit d6b86c7

File tree

4 files changed

+230
-0
lines changed

4 files changed

+230
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
AWS KMS master key provider examples.
5+
6+
These examples show how to use the KMS master key provider.
7+
"""
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
This example is provided as a reference for users migrating away from master key providers.
5+
We recommend that all new use should use keyrings.
6+
For examples using keyrings, see the ``examples/src/keyrings`` directory.
7+
8+
The KMS master key provider uses any key IDs that you specify on encrypt,
9+
but attempts to decrypt *any* data keys that were encrypted under a KMS CMK.
10+
This means that you do not need to know which CMKs were used to encrypt a message.
11+
12+
This example shows how to configure and use a KMS master key provider to decrypt without provider key IDs.
13+
14+
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#master-key-provider
15+
16+
For an example of how to use the KMS master key provider with CMKs in multiple regions,
17+
see the ``master_key_provider/aws_kms/multiple_regions`` example.
18+
"""
19+
import aws_encryption_sdk
20+
from aws_encryption_sdk.key_providers.kms import KMSMasterKey, KMSMasterKeyProvider
21+
22+
23+
def run(aws_kms_cmk, source_plaintext):
24+
# type: (str, bytes) -> None
25+
"""Demonstrate configuring a KMS master key provider for decryption.
26+
27+
:param str aws_kms_cmk: The ARN of an AWS KMS CMK that protects data keys
28+
:param bytes source_plaintext: Plaintext to encrypt
29+
"""
30+
# Prepare your encryption context.
31+
# https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
32+
encryption_context = {
33+
"encryption": "context",
34+
"is not": "secret",
35+
"but adds": "useful metadata",
36+
"that can help you": "be confident that",
37+
"the data you are handling": "is what you think it is",
38+
}
39+
40+
# Create the master key that determines how your data keys are protected.
41+
encrypt_master_key = KMSMasterKey(key_id=aws_kms_cmk)
42+
43+
# Create a KMS master key provider to use on decrypt.
44+
decrypt_master_key_provider = KMSMasterKeyProvider()
45+
46+
# Encrypt your plaintext data.
47+
ciphertext, _encrypt_header = aws_encryption_sdk.encrypt(
48+
source=source_plaintext, encryption_context=encryption_context, key_provider=encrypt_master_key
49+
)
50+
51+
# Demonstrate that the ciphertext and plaintext are different.
52+
assert ciphertext != source_plaintext
53+
54+
# Decrypt your encrypted data using the KMS master key provider.
55+
#
56+
# You do not need to specify the encryption context on decrypt
57+
# because the header of the encrypted message includes the encryption context.
58+
decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=decrypt_master_key_provider)
59+
60+
# Demonstrate that the decrypted plaintext is identical to the original plaintext.
61+
assert decrypted == source_plaintext
62+
63+
# Verify that the encryption context used in the decrypt operation includes
64+
# the encryption context that you specified when encrypting.
65+
# The AWS Encryption SDK can add pairs, so don't require an exact match.
66+
#
67+
# In production, always use a meaningful encryption context.
68+
assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items())
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
This example is provided as a reference for users migrating away from master key providers.
5+
We recommend that all new use should use keyrings.
6+
For examples using keyrings, see the ``examples/src/keyrings`` directory.
7+
8+
This example shows how to configure and use a KMS master key provider with with CMKs in multiple regions.
9+
10+
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#master-key-provider
11+
12+
For an example of how to use the KMS master key with a single CMK,
13+
see the ``master_key_provider/aws_kms/single_cmk`` example.
14+
15+
For examples of how to use the KMS master key provider in discovery mode on decrypt,
16+
see the ``master_key_provider/aws_kms/discovery_decrypt``.
17+
"""
18+
import aws_encryption_sdk
19+
from aws_encryption_sdk.key_providers.kms import KMSMasterKey, KMSMasterKeyProvider
20+
21+
try: # Python 3.5.0 and 3.5.1 have incompatible typing modules
22+
from typing import Sequence # noqa pylint: disable=unused-import
23+
except ImportError: # pragma: no cover
24+
# We only actually need these imports when running the mypy checks
25+
pass
26+
27+
28+
def run(aws_kms_generator_cmk, aws_kms_additional_cmks, source_plaintext):
29+
# type: (str, Sequence[str], bytes) -> None
30+
"""Demonstrate an encrypt/decrypt cycle using a KMS master key provider with CMKs in multiple regions.
31+
32+
:param str aws_kms_generator_cmk: The ARN of the primary AWS KMS CMK
33+
:param List[str] aws_kms_additional_cmks: Additional ARNs of secondary KMS CMKs
34+
:param bytes source_plaintext: Plaintext to encrypt
35+
"""
36+
# Prepare your encryption context.
37+
# https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
38+
encryption_context = {
39+
"encryption": "context",
40+
"is not": "secret",
41+
"but adds": "useful metadata",
42+
"that can help you": "be confident that",
43+
"the data you are handling": "is what you think it is",
44+
}
45+
46+
# Create the master key provider that will encrypt your data keys under all requested CMKs.
47+
#
48+
# The KMS master key provider generates the data key using the first key ID in the list.
49+
key_ids = [aws_kms_generator_cmk]
50+
key_ids.extend(aws_kms_additional_cmks)
51+
master_key_provider = KMSMasterKeyProvider(key_ids=key_ids)
52+
53+
# Create master keys that each only use one of the CMKs.
54+
# We will use these later to demonstrate that any of the CMKs can be used to decrypt the message.
55+
single_cmk_master_key_that_generated = KMSMasterKey(key_id=aws_kms_generator_cmk)
56+
single_cmk_master_key_that_encrypted = KMSMasterKey(key_id=aws_kms_additional_cmks[0])
57+
58+
# Encrypt your plaintext data using the master key provider that uses all requests CMKs.
59+
ciphertext, encrypt_header = aws_encryption_sdk.encrypt(
60+
source=source_plaintext, encryption_context=encryption_context, key_provider=master_key_provider
61+
)
62+
63+
# Verify that the header contains the expected number of encrypted data keys (EDKs).
64+
# It should contain one EDK for each CMK.
65+
assert len(encrypt_header.encrypted_data_keys) == len(aws_kms_additional_cmks) + 1
66+
67+
# Demonstrate that the ciphertext and plaintext are different.
68+
assert ciphertext != source_plaintext
69+
70+
# Decrypt your encrypted data separately using the single-CMK master keys.
71+
#
72+
# You do not need to specify the encryption context on decrypt
73+
# because the header of the encrypted message includes the encryption context.
74+
decrypted_1, decrypt_header_1 = aws_encryption_sdk.decrypt(
75+
source=ciphertext, key_provider=single_cmk_master_key_that_generated
76+
)
77+
decrypted_2, decrypt_header_2 = aws_encryption_sdk.decrypt(
78+
source=ciphertext, key_provider=single_cmk_master_key_that_encrypted
79+
)
80+
81+
# Demonstrate that the decrypted plaintext is identical to the original plaintext.
82+
assert decrypted_1 == source_plaintext
83+
assert decrypted_2 == source_plaintext
84+
85+
# Verify that the encryption context used in the decrypt operation includes
86+
# the encryption context that you specified when encrypting.
87+
# The AWS Encryption SDK can add pairs, so don't require an exact match.
88+
#
89+
# In production, always use a meaningful encryption context.
90+
assert set(encryption_context.items()) <= set(decrypt_header_1.encryption_context.items())
91+
assert set(encryption_context.items()) <= set(decrypt_header_2.encryption_context.items())
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
This example is provided as a reference for users migrating away from master key providers.
5+
We recommend that all new use should use keyrings.
6+
For examples using keyrings, see the ``examples/src/keyrings`` directory.
7+
8+
This example shows how to configure and use a KMS master key with a single KMS CMK.
9+
10+
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#master-key-provider
11+
12+
For an example of how to use the KMS master key provider with CMKs in multiple regions,
13+
see the ``master_key_provider/aws_kms/multiple_regions`` example.
14+
15+
For examples of how to use the KMS master key provider in discovery mode on decrypt,
16+
see the ``master_key_provider/aws_kms/discovery_decrypt``.
17+
"""
18+
import aws_encryption_sdk
19+
from aws_encryption_sdk.key_providers.kms import KMSMasterKey
20+
21+
22+
def run(aws_kms_cmk, source_plaintext):
23+
# type: (str, bytes) -> None
24+
"""Demonstrate an encrypt/decrypt cycle using a KMS master key with a single CMK.
25+
26+
:param str aws_kms_cmk: The ARN of an AWS KMS CMK that protects data keys
27+
:param bytes source_plaintext: Plaintext to encrypt
28+
"""
29+
# Prepare your encryption context.
30+
# https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
31+
encryption_context = {
32+
"encryption": "context",
33+
"is not": "secret",
34+
"but adds": "useful metadata",
35+
"that can help you": "be confident that",
36+
"the data you are handling": "is what you think it is",
37+
}
38+
39+
# Create the master key that determines how your data keys are protected.
40+
master_key = KMSMasterKey(key_id=aws_kms_cmk)
41+
42+
# Encrypt your plaintext data.
43+
ciphertext, _encrypt_header = aws_encryption_sdk.encrypt(
44+
source=source_plaintext, encryption_context=encryption_context, key_provider=master_key
45+
)
46+
47+
# Demonstrate that the ciphertext and plaintext are different.
48+
assert ciphertext != source_plaintext
49+
50+
# Decrypt your encrypted data using the same master key you used on encrypt.
51+
#
52+
# You do not need to specify the encryption context on decrypt
53+
# because the header of the encrypted message includes the encryption context.
54+
decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=master_key)
55+
56+
# Demonstrate that the decrypted plaintext is identical to the original plaintext.
57+
assert decrypted == source_plaintext
58+
59+
# Verify that the encryption context used in the decrypt operation includes
60+
# the encryption context that you specified when encrypting.
61+
# The AWS Encryption SDK can add pairs, so don't require an exact match.
62+
#
63+
# In production, always use a meaningful encryption context.
64+
assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items())

0 commit comments

Comments
 (0)
0