Skip to content

Commit a818ea5

Browse files
committed
chore: add initial new-format examples
1 parent 78484eb commit a818ea5

File tree

4 files changed

+286
-0
lines changed

4 files changed

+286
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
This example shows how to use the streaming encrypt and decrypt APIs when working with files.
5+
6+
For the purposes of this example, we demonstrate using AWS KMS,
7+
but you can use other key management options with the AWS Encryption SDK.
8+
Look in the ``keyring`` and ``master_key_provider`` directories
9+
for examples that demonstrate how to use other key management configurations.
10+
"""
11+
import filecmp
12+
13+
import aws_encryption_sdk
14+
from aws_encryption_sdk.keyrings.aws_kms import KmsKeyring
15+
16+
17+
def run(aws_kms_cmk_arn, source_plaintext_filename):
18+
# type: (str, str) -> None
19+
"""Demonstrate an encrypt/decrypt cycle using the streaming encrypt/decrypt APIs to work with files.
20+
21+
:param str aws_kms_cmk_arn: AWS KMS CMK ARN to use to protect data keys
22+
:param str source_plaintext_filename: Path to plaintext file to encrypt
23+
"""
24+
# We assume that you can also write in the directory containing the plaintext file,
25+
# so that is where we will put all of the results.
26+
ciphertext_filename = source_plaintext_filename + ".encrypted"
27+
decrypted_filename = ciphertext_filename + ".decrypted"
28+
29+
# Prepare your encryption context.
30+
encryption_context = {
31+
"encryption": "context",
32+
"is not": "secret",
33+
"but adds": "useful metadata",
34+
"that can help you": "be confident that",
35+
"the data you are handling": "is what you think it is",
36+
}
37+
38+
# Create the keyring that determines how your keys are protected.
39+
keyring = KmsKeyring(generator_key_id=aws_kms_cmk_arn)
40+
41+
# Open the files you want to work with.
42+
with open(source_plaintext_filename, "rb") as plaintext, open(ciphertext_filename, "wb") as ciphertext:
43+
# The streaming API provides you with a context manager
44+
# that you can read from similar to how you would read from a file.
45+
with aws_encryption_sdk.stream(
46+
mode="encrypt", source=plaintext, encryption_context=encryption_context, keyring=keyring
47+
) as encryptor:
48+
# Iterate through the chunks in the context manager
49+
# and write the results to the ciphertext.
50+
for chunk in encryptor:
51+
ciphertext.write(chunk)
52+
53+
# Verify that the ciphertext and plaintext are different.
54+
assert not filecmp.cmp(source_plaintext_filename, ciphertext_filename)
55+
56+
# Open the files you want to work with.
57+
with open(ciphertext_filename, "rb") as ciphertext, open(decrypted_filename, "wb") as decrypted:
58+
# Decrypt your encrypted data.
59+
#
60+
# We do not need to specify the encryption context on decrypt
61+
# because the header message includes the encryption context.
62+
with aws_encryption_sdk.stream(mode="decrypt", source=ciphertext, keyring=keyring) as decryptor:
63+
# One benefit of using the streaming API is that
64+
# we can check the encryption context in the header before we start decrypting.
65+
#
66+
# Verify that the encryption context used in the decrypt operation matches what you expect.
67+
# The AWS Encryption SDK can add pairs, so don't require an exact match.
68+
#
69+
# In production, always use a meaningful encryption context.
70+
assert set(encryption_context.items()) <= set(decryptor.header.encryption_context.items())
71+
72+
# Now that we are confident that the message is what we think it should be,
73+
# we can start decrypting.
74+
for chunk in decryptor:
75+
decrypted.write(chunk)
76+
77+
# Verify that the "cycled" (encrypted then decrypted) plaintext
78+
# is identical to the original plaintext.
79+
assert filecmp.cmp(source_plaintext_filename, decrypted_filename)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
This example shows how to use the streaming encrypt and decrypt APIs when working in memory.
5+
6+
For the purposes of this example, we demonstrate using AWS KMS,
7+
but you can use other key management options with the AWS Encryption SDK.
8+
Look in the ``keyring`` and ``master_key_provider`` directories
9+
for examples that demonstrate how to use other key management configurations.
10+
"""
11+
import io
12+
13+
import aws_encryption_sdk
14+
from aws_encryption_sdk.keyrings.aws_kms import KmsKeyring
15+
16+
17+
def run(aws_kms_cmk_arn, source_plaintext):
18+
# type: (str, bytes) -> None
19+
"""Demonstrate an encrypt/decrypt cycle using the streaming encrypt/decrypt APIs in-memory.
20+
21+
:param str aws_kms_cmk_arn: AWS KMS CMK ARN to use to protect data keys
22+
:param bytes source_plaintext: Plaintext to encrypt
23+
"""
24+
# Prepare your encryption context.
25+
encryption_context = {
26+
"encryption": "context",
27+
"is not": "secret",
28+
"but adds": "useful metadata",
29+
"that can help you": "be confident that",
30+
"the data you are handling": "is what you think it is",
31+
}
32+
33+
# Create the keyring that determines how your keys are protected.
34+
keyring = KmsKeyring(generator_key_id=aws_kms_cmk_arn)
35+
36+
ciphertext = io.BytesIO()
37+
38+
# The streaming API provides you with a context manager
39+
# that you can read from similar to how you would read from a file.
40+
with aws_encryption_sdk.stream(
41+
mode="encrypt", source=source_plaintext, encryption_context=encryption_context, keyring=keyring
42+
) as encryptor:
43+
# Iterate through the chunks in the context manager
44+
# and write the results to the ciphertext.
45+
for chunk in encryptor:
46+
ciphertext.write(chunk)
47+
48+
assert ciphertext.getvalue() != source_plaintext
49+
50+
# Reset the ciphertext stream position so that we can read from the beginning.
51+
ciphertext.seek(0)
52+
53+
# Decrypt your encrypted data.
54+
#
55+
# We do not need to specify the encryption context on decrypt
56+
# because the header message includes the encryption context.
57+
decrypted = io.BytesIO()
58+
with aws_encryption_sdk.stream(mode="decrypt", source=ciphertext, keyring=keyring) as decryptor:
59+
# One benefit of using the streaming API is that
60+
# we can check the encryption context in the header before we start decrypting.
61+
#
62+
# Verify that the encryption context used in the decrypt operation matches what you expect.
63+
# The AWS Encryption SDK can add pairs, so don't require an exact match.
64+
#
65+
# In production, always use a meaningful encryption context.
66+
assert set(encryption_context.items()) <= set(decryptor.header.encryption_context.items())
67+
68+
# Now that we are confident that the message is what we think it should be,
69+
# we can start decrypting.
70+
for chunk in decryptor:
71+
decrypted.write(chunk)
72+
73+
# Verify that the "cycled" (encrypted then decrypted) plaintext
74+
# is identical to the original plaintext.
75+
assert decrypted.getvalue() == source_plaintext

examples/src/oneshot_defaults.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
This example shows how to use the one-shot encrypt and decrypt APIs.
5+
6+
For the purposes of this example, we demonstrate using AWS KMS,
7+
but you can use other key management options with the AWS Encryption SDK.
8+
Look in the ``keyring`` and ``master_key_provider`` directories
9+
for examples that demonstrate how to use other key management configurations.
10+
"""
11+
import aws_encryption_sdk
12+
from aws_encryption_sdk.keyrings.aws_kms import KmsKeyring
13+
14+
15+
def run(aws_kms_cmk_arn, source_plaintext):
16+
# type: (str, bytes) -> None
17+
"""Demonstrate an encrypt/decrypt cycle using the one-shot encrypt/decrypt APIs.
18+
19+
:param str aws_kms_cmk_arn: AWS KMS CMK ARN to use to protect data keys
20+
:param bytes source_plaintext: Plaintext to encrypt
21+
"""
22+
# Prepare your encryption context.
23+
encryption_context = {
24+
"encryption": "context",
25+
"is not": "secret",
26+
"but adds": "useful metadata",
27+
"that can help you": "be confident that",
28+
"the data you are handling": "is what you think it is",
29+
}
30+
31+
# Create the keyring that determines how your keys are protected.
32+
keyring = KmsKeyring(generator_key_id=aws_kms_cmk_arn)
33+
34+
# Encrypt your plaintext data.
35+
ciphertext, _encrypt_header = aws_encryption_sdk.encrypt(
36+
source=source_plaintext, encryption_context=encryption_context, keyring=keyring
37+
)
38+
39+
# Verify that the ciphertext and plaintext are different.
40+
assert ciphertext != source_plaintext
41+
42+
# Decrypt your encrypted data.
43+
#
44+
# We do not need to specify the encryption context on decrypt
45+
# because the header message includes the encryption context.
46+
decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring)
47+
48+
# Verify that the "cycled" (encrypted then decrypted) plaintext
49+
# is identical to the original plaintext.
50+
assert decrypted == source_plaintext
51+
52+
# Verify that the encryption context used in the decrypt operation matches what you expect.
53+
# The AWS Encryption SDK can add pairs, so don't require an exact match.
54+
#
55+
# In production, always use a meaningful encryption context.
56+
assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items())

examples/src/oneshot_unsigned.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""
4+
This example shows how to specify an algorithm suite
5+
when using the one-shot encrypt and decrypt APIs.
6+
7+
For the purposes of this example, we demonstrate using AWS KMS,
8+
but you can use other key management options with the AWS Encryption SDK.
9+
Look in the ``keyring`` and ``master_key_provider`` directories
10+
for examples that demonstrate how to use other key management configurations.
11+
12+
The default algorithm suite includes a message-level signature
13+
that protects you from an attacker who has *decrypt* but not *encrypt* capability
14+
for a wrapping key that you used when encrypting a message
15+
under multiple wrapping keys.
16+
17+
However, if all of your readers and writers have the same permissions,
18+
then this additional protection does not always add value.
19+
This example shows you how to select another algorithm suite
20+
that has all of the other properties of the default suite
21+
but does not include a message-level signature.
22+
"""
23+
import aws_encryption_sdk
24+
from aws_encryption_sdk.identifiers import AlgorithmSuite
25+
from aws_encryption_sdk.keyrings.aws_kms import KmsKeyring
26+
27+
28+
def run(aws_kms_cmk_arn, source_plaintext):
29+
# type: (str, bytes) -> None
30+
"""Demonstrate requesting a specific algorithm suite through the one-shot encrypt/decrypt APIs.
31+
32+
:param str aws_kms_cmk_arn: AWS KMS CMK ARN to use to protect data keys
33+
:param bytes source_plaintext: Plaintext to encrypt
34+
"""
35+
# Prepare your encryption context.
36+
encryption_context = {
37+
"encryption": "context",
38+
"is not": "secret",
39+
"but adds": "useful metadata",
40+
"that can help you": "be confident that",
41+
"the data you are handling": "is what you think it is",
42+
}
43+
44+
# Create the keyring that determines how your keys are protected.
45+
keyring = KmsKeyring(generator_key_id=aws_kms_cmk_arn)
46+
47+
# Encrypt your plaintext data.
48+
ciphertext, _encrypt_header = aws_encryption_sdk.encrypt(
49+
source=source_plaintext,
50+
encryption_context=encryption_context,
51+
keyring=keyring,
52+
# Here we can specify the algorithm suite that we want to use.
53+
algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA256,
54+
)
55+
56+
# Verify that the ciphertext and plaintext are different.
57+
assert ciphertext != source_plaintext
58+
59+
# Decrypt your encrypted data.
60+
#
61+
# We do not need to specify the encryption context on decrypt
62+
# because the header message includes the encryption context.
63+
#
64+
# We do not need to specify the algorithm suite on decrypt
65+
# because the header message includes the algorithm suite identifier.
66+
decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring)
67+
68+
# Verify that the "cycled" (encrypted then decrypted) plaintext
69+
# is identical to the original plaintext.
70+
assert decrypted == source_plaintext
71+
72+
# Verify that the encryption context used in the decrypt operation matches what you expect.
73+
# The AWS Encryption SDK can add pairs, so don't require an exact match.
74+
#
75+
# In production, always use a meaningful encryption context.
76+
assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items())

0 commit comments

Comments
 (0)