Skip to content

fix(Examples): Validate EC on decrypt #697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions examples/src/aws_kms_discovery_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,15 @@ def encrypt_and_decrypt_with_keyring(
# successfully decrypted. The resulting data key is used to decrypt the
# ciphertext's message.
# If all calls to KMS fail, the decryption fails.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=discovery_keyring
keyring=discovery_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to Ryan, we want to tell the customer to always provide the encryption context during decrypt. I wonder if it'll be better if we remove the word "Verify" and just say "Enter the encryption context supplied to the encrypt method".

Same goes for Line #192 in this file and all other examples.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, I slightly preferred "Provide" instead of "Enter"

Good catch on migration examples, I updated those to supply EC on decrypt if decrypting with keyring.
I also added manual EC validation if decrypting with MKP since MKPs don't support EC validation on decrypt.

encryption_context=encryption_context,
)

# 9. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
Expand Down Expand Up @@ -192,7 +189,10 @@ def encrypt_and_decrypt_with_keyring(
try:
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=discovery_keyring_bob
keyring=discovery_keyring_bob,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

raise AssertionError("Decrypt using discovery keyring with wrong AWS Account ID should"
Expand Down
15 changes: 6 additions & 9 deletions examples/src/aws_kms_discovery_multi_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,15 @@ def encrypt_and_decrypt_with_keyring(
# All of this is done serially, until a success occurs or all keyrings have
# failed all (filtered) EDKs.
# KMS Discovery Keyrings will attempt to decrypt Multi Region Keys (MRKs) and regular KMS Keys.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=discovery_multi_keyring
keyring=discovery_multi_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 9. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
15 changes: 6 additions & 9 deletions examples/src/aws_kms_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,15 @@ def encrypt_and_decrypt_with_keyring(
"Ciphertext and plaintext data are the same. Invalid encryption"

# 7. Decrypt your encrypted data using the same keyring you used on encrypt.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=kms_keyring
keyring=kms_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 8. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
15 changes: 6 additions & 9 deletions examples/src/aws_kms_mrk_discovery_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,14 @@ def encrypt_and_decrypt_with_keyring(
)

# 7. Decrypt your encrypted data using the discovery keyring.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=decrypt_discovery_keyring
keyring=decrypt_discovery_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 8. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA
15 changes: 6 additions & 9 deletions examples/src/aws_kms_mrk_discovery_multi_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,17 +172,14 @@ def encrypt_and_decrypt_with_keyring(
# All of this is done serially, until a success occurs or all keyrings have failed
# all (filtered) EDKs. KMS MRK Discovery Keyrings will attempt to decrypt
# Multi Region Keys (MRKs) and regular KMS Keys.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=decrypt_discovery_keyring
keyring=decrypt_discovery_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 8. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA
15 changes: 6 additions & 9 deletions examples/src/aws_kms_mrk_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,15 @@ def encrypt_and_decrypt_with_keyring(
)

# 7. Decrypt your encrypted data using the same keyring you used on encrypt.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=decrypt_keyring
keyring=decrypt_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 8. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
34 changes: 14 additions & 20 deletions examples/src/aws_kms_mrk_multi_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,15 @@ def encrypt_and_decrypt_with_keyring(
# 6. Decrypt your encrypted data using the same AwsKmsMrkMultiKeyring you used on encrypt.
# It will decrypt the data using the generator key (in this case, the MRK), since that is
# the first available KMS key on the keyring that is capable of decrypting the data.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=kms_mrk_multi_keyring
keyring=kms_mrk_multi_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 7. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 7. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
Expand All @@ -144,7 +141,7 @@ def encrypt_and_decrypt_with_keyring(
# multi-keyring used to encrypt the data is also capable of decrypting the data.
# (This is an example for demonstration; you do not need to do this in your own code.)

# 9. Create a single AwsKmsMrkKeyring with the replica KMS MRK from the second region.
# 8. Create a single AwsKmsMrkKeyring with the replica KMS MRK from the second region.

# Create a boto3 client for KMS in the second region which is the region for mrk_replica_key_id.
second_region_kms_client = boto3.client('kms', region_name=mrk_replica_decrypt_region)
Expand All @@ -158,19 +155,16 @@ def encrypt_and_decrypt_with_keyring(
input=second_region_mrk_keyring_input
)

# 10. Decrypt your encrypted data using the second region AwsKmsMrkKeyring
plaintext_bytes_second_region, dec_header_second_region = client.decrypt(
# 9. Decrypt your encrypted data using the second region AwsKmsMrkKeyring
plaintext_bytes_second_region, _ = client.decrypt(
source=ciphertext,
keyring=second_region_mrk_keyring
keyring=second_region_mrk_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 11. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header_second_region.encryption_context[k], \
"Encryption context does not match expected values"

# 12. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes_second_region == EXAMPLE_DATA

Expand Down
15 changes: 12 additions & 3 deletions examples/src/aws_kms_multi_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ def encrypt_and_decrypt_with_keyring(
# 6a. Decrypt your encrypted data using the same multi_keyring you used on encrypt.
plaintext_bytes_multi_keyring, _ = client.decrypt(
source=ciphertext,
keyring=kms_multi_keyring
keyring=kms_multi_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 6b. Demonstrate that the decrypted plaintext is identical to the original plaintext.
Expand Down Expand Up @@ -164,7 +167,10 @@ def encrypt_and_decrypt_with_keyring(
# 7c. Decrypt your encrypted data using the default_region_kms_keyring.
plaintext_bytes_default_region_kms_keyring, _ = client.decrypt(
source=ciphertext,
keyring=default_region_kms_keyring
keyring=default_region_kms_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 7d. Demonstrate that the decrypted plaintext is identical to the original plaintext.
Expand Down Expand Up @@ -192,7 +198,10 @@ def encrypt_and_decrypt_with_keyring(
# 8c. Decrypt your encrypted data using the second_region_kms_keyring.
plaintext_bytes_second_region_kms_keyring, _ = client.decrypt(
source=ciphertext,
keyring=second_region_kms_keyring
keyring=second_region_kms_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 8d. Demonstrate that the decrypted plaintext is identical to the original plaintext.
Expand Down
15 changes: 6 additions & 9 deletions examples/src/aws_kms_rsa_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,15 @@ def encrypt_and_decrypt_with_keyring(
"Ciphertext and plaintext data are the same. Invalid encryption"

# 7. Decrypt your encrypted data using the same keyring you used on encrypt.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
keyring=kms_rsa_keyring
keyring=kms_rsa_keyring,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 8. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
15 changes: 6 additions & 9 deletions examples/src/default_cryptographic_materials_manager_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,15 @@ def encrypt_and_decrypt_with_default_cmm(
"Ciphertext and plaintext data are the same. Invalid encryption"

# 7. Decrypt your encrypted data using the same cmm you used on encrypt.
plaintext_bytes, dec_header = client.decrypt(
plaintext_bytes, _ = client.decrypt(
source=ciphertext,
materials_manager=cmm
materials_manager=cmm,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context,
)

# 8. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 9. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
6 changes: 0 additions & 6 deletions examples/src/file_streaming_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,6 @@ def encrypt_and_decrypt_with_keyring(
for chunk in decryptor:
pt_file.write(chunk)

# 9. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == decryptor.header.encryption_context[k], \
"Encryption context does not match expected values"

# 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert filecmp.cmp(plaintext_filename, decrypted_filename), \
Expand Down
23 changes: 18 additions & 5 deletions examples/src/hierarchical_keyring_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ def encrypt_and_decrypt_with_keyring(
try:
client.decrypt(
source=ciphertext_a,
keyring=hierarchical_keyring_b
keyring=hierarchical_keyring_b,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context_a,
)
except AWSEncryptionSDKClientError:
pass
Expand All @@ -210,22 +213,32 @@ def encrypt_and_decrypt_with_keyring(
try:
client.decrypt(
source=ciphertext_b,
keyring=hierarchical_keyring_a
keyring=hierarchical_keyring_a,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context_b,
)
except AWSEncryptionSDKClientError:
pass

# 10. Demonstrate that data encrypted by one tenant's branch key can be decrypted by that tenant,
# 11. Demonstrate that data encrypted by one tenant's branch key can be decrypted by that tenant,
# and that the decrypted data matches the input data.
plaintext_bytes_a, _ = client.decrypt(
source=ciphertext_a,
keyring=hierarchical_keyring_a
keyring=hierarchical_keyring_a,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context_a,
)
assert plaintext_bytes_a == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"

plaintext_bytes_b, _ = client.decrypt(
source=ciphertext_b,
keyring=hierarchical_keyring_b
keyring=hierarchical_keyring_b,
# Verify that the encryption context in the result contains the
# encryption context supplied to the encrypt method
encryption_context=encryption_context_b,
)
assert plaintext_bytes_b == EXAMPLE_DATA, \
"Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
Loading
Loading