Skip to content

Commit 1031f6e

Browse files
MeghaShettymattsb42-aws
authored andcommitted
Adding example one_kms_cmk (#158)
* Adding example one_kms_cmk * Changes in one_kms_cmk and made random plaintext static * Changes in one_kms_cmk and made random plaintext static * Update one_kms_cmk.py * Changes in one_kms_cmk and made random plaintext static * Formatting changes in some files * Minor changes in some files * Adding example: Encryption decryption of streaming data using one KMS CMK * Added 'b' to the static plaintext * Wrapped static plaintext to <= 120 characters * Added docstrings * Corrected docstrings * Changed imports for same modules to be in the same statement and changed name of instance variable * Changed handle back
1 parent 433adfd commit 1031f6e

9 files changed

+213
-7
lines changed

examples/src/basic_file_encryption_with_multiple_providers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,4 @@ def cycle_file(key_arn, source_plaintext_filename, botocore_session=None):
130130
pair in static_decryptor.header.encryption_context.items()
131131
for pair in encryptor.header.encryption_context.items()
132132
)
133-
return ciphertext_filename, cycled_kms_plaintext_filename, cycled_static_plaintext_filename
133+
return (ciphertext_filename, cycled_kms_plaintext_filename, cycled_static_plaintext_filename)

examples/src/one_kms_cmk.py

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
"""Example showing basic encryption and decryption of a value already in memory using one KMS CMK."""
14+
import aws_encryption_sdk
15+
16+
17+
def encrypt_decrypt(key_arn, source_plaintext, botocore_session=None):
18+
"""Encrypts and then decrypts a string under one KMS customer master key (CMK).
19+
20+
:param str key_arn: Amazon Resource Name (ARN) of the KMS CMK
21+
:param bytes source_plaintext: Data to encrypt
22+
:param botocore_session: existing botocore session instance
23+
:type botocore_session: botocore.session.Session
24+
"""
25+
kwargs = dict(key_ids=[key_arn])
26+
27+
if botocore_session is not None:
28+
kwargs["botocore_session"] = botocore_session
29+
30+
# Create master key provider using the ARN of the key and the session (botocore_session)
31+
kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kwargs)
32+
33+
# Encrypt the plaintext using the AWS Encryption SDK. It returns the encrypted message and the header
34+
ciphertext, encrypted_message_header = aws_encryption_sdk.encrypt(
35+
source=source_plaintext, key_provider=kms_key_provider
36+
)
37+
38+
# Decrypt the encrypted message using the AWS Encryption SDK. It returns the decrypted message and the header
39+
plaintext, decrypted_message_header = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=kms_key_provider)
40+
41+
# Check if the original message and the decrypted message are the same
42+
assert source_plaintext == plaintext
43+
44+
# Check if the headers of the encrypted message and decrypted message match
45+
assert all(
46+
pair in encrypted_message_header.encryption_context.items()
47+
for pair in decrypted_message_header.encryption_context.items()
48+
)
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
"""Example showing basic encryption and decryption of streaming data in memory using one KMS CMK."""
14+
import filecmp
15+
16+
import aws_encryption_sdk
17+
18+
19+
def encrypt_decrypt_stream(key_arn, source_plaintext_filename, botocore_session=None):
20+
"""Encrypts and then decrypts streaming data under one KMS customer master key (CMK).
21+
22+
:param str key_arn: Amazon Resource Name (ARN) of the KMS CMK
23+
:param str source_plaintext_filename: Filename of file to encrypt
24+
:param botocore_session: existing botocore session instance
25+
:type botocore_session: botocore.session.Session
26+
"""
27+
kwargs = dict()
28+
29+
kwargs["key_ids"] = [key_arn]
30+
31+
if botocore_session is not None:
32+
kwargs["botocore_session"] = botocore_session
33+
34+
# Create master key provider using the ARN of the key and the session (botocore_session)
35+
kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kwargs)
36+
37+
ciphertext_filename = source_plaintext_filename + ".encrypted"
38+
decrypted_text_filename = source_plaintext_filename + ".decrypted"
39+
40+
# Encrypt the plaintext using the AWS Encryption SDK.
41+
with open(source_plaintext_filename, "rb") as plaintext, open(ciphertext_filename, "wb") as ciphertext:
42+
with aws_encryption_sdk.stream(source=plaintext, mode="e", key_provider=kms_key_provider) as encryptor:
43+
for chunk in encryptor:
44+
ciphertext.write(chunk)
45+
46+
# Decrypt the encrypted message using the AWS Encryption SDK.
47+
with open(ciphertext_filename, "rb") as ciphertext, open(decrypted_text_filename, "wb") as plaintext:
48+
with aws_encryption_sdk.stream(source=ciphertext, mode="d", key_provider=kms_key_provider) as decryptor:
49+
for chunk in decryptor:
50+
plaintext.write(chunk)
51+
52+
# Check if the original message and the decrypted message are the same
53+
assert filecmp.cmp(source_plaintext_filename, decrypted_text_filename)
54+
55+
# Check if the headers of the encrypted message and decrypted message match
56+
assert all(
57+
pair in encryptor.header.encryption_context.items() for pair in decryptor.header.encryption_context.items()
58+
)
59+
return ciphertext_filename, decrypted_text_filename

examples/test/examples_test_utils.py

+30
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,34 @@
1717
os.environ["AWS_ENCRYPTION_SDK_EXAMPLES_TESTING"] = "yes"
1818
sys.path.extend([os.sep.join([os.path.dirname(__file__), "..", "..", "test", "integration"])])
1919

20+
static_plaintext = (
21+
b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
22+
b"Praesent non feugiat leo. Aenean iaculis tellus ut velit consectetur, "
23+
b"quis convallis orci eleifend. Sed eu dictum sapien. Nulla facilisi. Suspendisse potenti. "
24+
b"Proin vehicula vehicula maximus. Donec varius et elit vel rutrum. Nulla lacinia neque turpis,"
25+
b" quis consequat orci pharetra et. Etiam consequat ullamcorper mauris. Vivamus molestie mollis "
26+
b"mauris a gravida. Curabitur sed bibendum nisl. Cras varius tortor non erat sodales, quis congue"
27+
b" tellus laoreet. Etiam fermentum purus eu diam sagittis, vitae commodo est vehicula. "
28+
b"Nulla feugiat viverra orci vel interdum. Quisque pulvinar elit eget nulla facilisis varius. "
29+
b"Mauris at suscipit sem. Aliquam in purus ut velit fringilla volutpat id non mi. "
30+
b"Curabitur quis nunc eleifend, ornare lectus non, fringilla quam. Nam maximus volutpat placerat. "
31+
b"Nulla ullamcorper lorem velit, nec sagittis ex tristique posuere. Aliquam fringilla magna commodo"
32+
b" libero faucibus tempor. Vestibulum non ligula tincidunt, finibus sapien in, sollicitudin "
33+
b"ex. Pellentesque congue laoreet mi in condimentum. Cras convallis nisi ac nunc tincidunt "
34+
b"venenatis. Suspendisse urna elit, cursus eu lacus a, aliquet porttitor mi. "
35+
b"Nulla vel congue nibh, sed condimentum dui. Ut ante ligula, blandit eu finibus nec, "
36+
b"scelerisque quis eros. Maecenas gravida odio eget nibh dictum, dictum varius lacus interdum. "
37+
b"Integer quis nulla vulputate, rhoncus diam vitae, mollis mauris. Sed ut porttitor dolor. "
38+
b"Fusce ut justo a ex bibendum imperdiet nec sit amet magna. Sed ullamcorper luctus augue, "
39+
b"tempor viverra elit interdum sed. Cras sit amet arcu eu turpis molestie sollicitudin. "
40+
b"Curabitur fermentum varius nibh, ut aliquet nisi. Aliquam id tempus tellus. "
41+
b"Nulla porttitor nulla at nibh interdum, quis sollicitudin erat egestas. "
42+
b"Ut blandit mauris quis efficitur efficitur. Morbi neque sapien, posuere ut aliquam eget, "
43+
b"aliquam at velit. Morbi sit amet rhoncus felis, et hendrerit sem. Nulla porta dictum ligula "
44+
b"eget iaculis. Cras lacinia ligula quis risus ultrices, sed consectetur metus imperdiet. "
45+
b"Nullam id enim vestibulum nibh ultricies auctor. Morbi neque lacus, faucibus vitae commodo quis, "
46+
b"malesuada sed velit."
47+
)
48+
49+
2050
from integration_test_utils import get_cmk_arn # noqa pylint: disable=unused-import,import-error

examples/test/test_i_basic_encryption.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,17 @@
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
1313
"""Unit test suite for the Strings examples in the AWS-hosted documentation."""
14-
import os
15-
1614
import botocore.session
1715
import pytest
1816

1917
from ..src.basic_encryption import cycle_string
20-
from .examples_test_utils import get_cmk_arn
18+
from .examples_test_utils import get_cmk_arn, static_plaintext
2119

2220

2321
pytestmark = [pytest.mark.examples]
2422

2523

2624
def test_cycle_string():
27-
plaintext = os.urandom(1024)
25+
plaintext = static_plaintext
2826
cmk_arn = get_cmk_arn()
2927
cycle_string(key_arn=cmk_arn, source_plaintext=plaintext, botocore_session=botocore.session.Session())

examples/test/test_i_basic_file_encryption_with_multiple_providers.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from ..src.basic_file_encryption_with_multiple_providers import cycle_file
2121
from .examples_test_utils import get_cmk_arn
22+
from .examples_test_utils import static_plaintext
2223

2324

2425
pytestmark = [pytest.mark.examples]
@@ -28,7 +29,7 @@ def test_cycle_file():
2829
cmk_arn = get_cmk_arn()
2930
handle, filename = tempfile.mkstemp()
3031
with open(filename, "wb") as f:
31-
f.write(os.urandom(1024))
32+
f.write(static_plaintext)
3233
try:
3334
new_files = cycle_file(
3435
key_arn=cmk_arn, source_plaintext_filename=filename, botocore_session=botocore.session.Session()

examples/test/test_i_basic_file_encryption_with_raw_key_provider.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import pytest
1818

1919
from ..src.basic_file_encryption_with_raw_key_provider import cycle_file
20+
from .examples_test_utils import static_plaintext
2021

2122

2223
pytestmark = [pytest.mark.examples]
@@ -25,7 +26,7 @@
2526
def test_cycle_file():
2627
handle, filename = tempfile.mkstemp()
2728
with open(filename, "wb") as f:
28-
f.write(os.urandom(1024))
29+
f.write(static_plaintext)
2930
try:
3031
new_files = cycle_file(source_plaintext_filename=filename)
3132
for f in new_files:

examples/test/test_i_one_kms_cmk.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
"""Unit test suite for the encryption and decryption using one KMS CMK example."""
14+
15+
import botocore.session
16+
import pytest
17+
18+
from ..src.one_kms_cmk import encrypt_decrypt
19+
from .examples_test_utils import get_cmk_arn
20+
from .examples_test_utils import static_plaintext
21+
22+
23+
pytestmark = [pytest.mark.examples]
24+
25+
26+
def test_one_kms_cmk():
27+
plaintext = static_plaintext
28+
cmk_arn = get_cmk_arn()
29+
encrypt_decrypt(key_arn=cmk_arn, source_plaintext=plaintext, botocore_session=botocore.session.Session())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
"""Unit test suite for the encryption and decryption of streaming data using one KMS CMK example."""
14+
import os
15+
import tempfile
16+
17+
import botocore.session
18+
import pytest
19+
20+
from ..src.one_kms_cmk_streaming_data import encrypt_decrypt_stream
21+
from .examples_test_utils import get_cmk_arn, static_plaintext
22+
23+
24+
pytestmark = [pytest.mark.examples]
25+
26+
27+
def test_one_kms_cmk_streaming_data():
28+
cmk_arn = get_cmk_arn()
29+
handle, filename = tempfile.mkstemp()
30+
with open(filename, "wb") as f:
31+
f.write(static_plaintext)
32+
try:
33+
new_files = encrypt_decrypt_stream(
34+
key_arn=cmk_arn, source_plaintext_filename=filename, botocore_session=botocore.session.Session()
35+
)
36+
for f in new_files:
37+
os.remove(f)
38+
finally:
39+
os.close(handle)
40+
os.remove(filename)

0 commit comments

Comments
 (0)