diff --git a/examples/src/aws_kms_discovery_keyring_example.py b/examples/src/aws_kms_discovery_keyring_example.py index d78121bc3..cef894360 100644 --- a/examples/src/aws_kms_discovery_keyring_example.py +++ b/examples/src/aws_kms_discovery_keyring_example.py @@ -153,18 +153,14 @@ 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, + # Provide the encryption context that was 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" @@ -192,7 +188,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" diff --git a/examples/src/aws_kms_discovery_multi_keyring_example.py b/examples/src/aws_kms_discovery_multi_keyring_example.py index 9381a740b..82454cc34 100644 --- a/examples/src/aws_kms_discovery_multi_keyring_example.py +++ b/examples/src/aws_kms_discovery_multi_keyring_example.py @@ -151,18 +151,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 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, + # Provide the encryption context that was 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" diff --git a/examples/src/aws_kms_keyring_example.py b/examples/src/aws_kms_keyring_example.py index 8977e3750..5b07e5210 100644 --- a/examples/src/aws_kms_keyring_example.py +++ b/examples/src/aws_kms_keyring_example.py @@ -97,18 +97,14 @@ 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, + # Provide the encryption context that was 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" diff --git a/examples/src/aws_kms_mrk_discovery_keyring_example.py b/examples/src/aws_kms_mrk_discovery_keyring_example.py index 23d6cb322..fecc332f9 100644 --- a/examples/src/aws_kms_mrk_discovery_keyring_example.py +++ b/examples/src/aws_kms_mrk_discovery_keyring_example.py @@ -163,17 +163,13 @@ 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, + # Provide the encryption context that was 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 diff --git a/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py b/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py index adb249e2a..ef02caa61 100644 --- a/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py +++ b/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py @@ -172,17 +172,13 @@ 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, + # Provide the encryption context that was 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 diff --git a/examples/src/aws_kms_mrk_keyring_example.py b/examples/src/aws_kms_mrk_keyring_example.py index edb3cc410..ee7f570f0 100644 --- a/examples/src/aws_kms_mrk_keyring_example.py +++ b/examples/src/aws_kms_mrk_keyring_example.py @@ -132,18 +132,14 @@ 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, + # Provide the encryption context that was 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" diff --git a/examples/src/aws_kms_mrk_multi_keyring_example.py b/examples/src/aws_kms_mrk_multi_keyring_example.py index 6b1e64eec..71ee0f00b 100644 --- a/examples/src/aws_kms_mrk_multi_keyring_example.py +++ b/examples/src/aws_kms_mrk_multi_keyring_example.py @@ -124,18 +124,14 @@ 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, + # Provide the encryption context that was 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" @@ -144,7 +140,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) @@ -158,19 +154,15 @@ 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, + # Provide the encryption context that was 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 diff --git a/examples/src/aws_kms_multi_keyring_example.py b/examples/src/aws_kms_multi_keyring_example.py index 7cba36167..4e74eafc8 100644 --- a/examples/src/aws_kms_multi_keyring_example.py +++ b/examples/src/aws_kms_multi_keyring_example.py @@ -133,7 +133,9 @@ 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, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=encryption_context, ) # 6b. Demonstrate that the decrypted plaintext is identical to the original plaintext. @@ -164,7 +166,9 @@ 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, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=encryption_context, ) # 7d. Demonstrate that the decrypted plaintext is identical to the original plaintext. @@ -192,7 +196,9 @@ 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, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=encryption_context, ) # 8d. Demonstrate that the decrypted plaintext is identical to the original plaintext. diff --git a/examples/src/aws_kms_rsa_keyring_example.py b/examples/src/aws_kms_rsa_keyring_example.py index fd05fc20b..81c613c99 100644 --- a/examples/src/aws_kms_rsa_keyring_example.py +++ b/examples/src/aws_kms_rsa_keyring_example.py @@ -103,18 +103,14 @@ 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, + # Provide the encryption context that was 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" diff --git a/examples/src/default_cryptographic_materials_manager_example.py b/examples/src/default_cryptographic_materials_manager_example.py index 15a9f22cf..f6312e208 100644 --- a/examples/src/default_cryptographic_materials_manager_example.py +++ b/examples/src/default_cryptographic_materials_manager_example.py @@ -109,18 +109,14 @@ 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, + # Provide the encryption context that was 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" diff --git a/examples/src/file_streaming_example.py b/examples/src/file_streaming_example.py index 3f547d220..c7c3cff05 100644 --- a/examples/src/file_streaming_example.py +++ b/examples/src/file_streaming_example.py @@ -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), \ diff --git a/examples/src/hierarchical_keyring_example.py b/examples/src/hierarchical_keyring_example.py index 00dadf9d8..92efa2865 100644 --- a/examples/src/hierarchical_keyring_example.py +++ b/examples/src/hierarchical_keyring_example.py @@ -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 @@ -210,22 +213,30 @@ 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, + # Provide the encryption context that was 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, + # Provide the encryption context that was 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" diff --git a/examples/src/migration/migration_aws_kms_key_example.py b/examples/src/migration/migration_aws_kms_key_example.py index 28b8193e3..e0a577d20 100644 --- a/examples/src/migration/migration_aws_kms_key_example.py +++ b/examples/src/migration/migration_aws_kms_key_example.py @@ -115,14 +115,14 @@ def migration_aws_kms_key( aws_kms_master_key_provider = create_key_provider(kms_key_id=kms_key_id) # 2a. Encrypt EXAMPLE_DATA using AWS KMS Keyring - ciphertext_keyring, _ = client.encrypt( + ciphertext_keyring, encrypted_header_keyring = client.encrypt( source=EXAMPLE_DATA, keyring=aws_kms_keyring, encryption_context=DEFAULT_ENCRYPTION_CONTEXT ) # 2b. Encrypt EXAMPLE_DATA using AWS KMS Master Key Provider - ciphertext_mkp, _ = client.encrypt( + ciphertext_mkp, encrypted_header_mkp = client.encrypt( source=EXAMPLE_DATA, key_provider=aws_kms_master_key_provider, encryption_context=DEFAULT_ENCRYPTION_CONTEXT @@ -137,14 +137,25 @@ def migration_aws_kms_key( # resulting plaintext is the same and also equal to EXAMPLE_DATA decrypted_ciphertext_keyring_using_keyring, _ = client.decrypt( source=ciphertext_keyring, - keyring=aws_kms_keyring + keyring=aws_kms_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=DEFAULT_ENCRYPTION_CONTEXT, ) - decrypted_ciphertext_keyring_using_mkp, _ = client.decrypt( + decrypted_ciphertext_keyring_using_mkp, decrypted_header_keyring_using_mkp = client.decrypt( source=ciphertext_keyring, key_provider=aws_kms_master_key_provider ) + # Legacy MasterKeyProviders do not support providing encryption context on decrypt. + # If decrypting with a legacy MasterKeyProvider, you should manually verify + # that the encryption context used in the decrypt operation + # includes all key pairs from the encrypt operation. (The SDK can add pairs, so don't require an exact match.) + assert all( + pair in decrypted_header_keyring_using_mkp.encryption_context.items() + for pair in encrypted_header_keyring.encryption_context.items() + ) + assert decrypted_ciphertext_keyring_using_keyring == decrypted_ciphertext_keyring_using_mkp \ and decrypted_ciphertext_keyring_using_keyring == EXAMPLE_DATA, \ "Decrypted outputs using keyring and master key provider are not the same" @@ -153,14 +164,25 @@ def migration_aws_kms_key( # resulting plaintext is the same and also equal to EXAMPLE_DATA decrypted_ciphertext_mkp_using_keyring, _ = client.decrypt( source=ciphertext_mkp, - keyring=aws_kms_keyring + keyring=aws_kms_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=DEFAULT_ENCRYPTION_CONTEXT, ) - decrypted_ciphertext_mkp_using_mkp, _ = client.decrypt( + decrypted_ciphertext_mkp_using_mkp, decrypted_header_mkp_using_mkp = client.decrypt( source=ciphertext_mkp, key_provider=aws_kms_master_key_provider ) + # Legacy MasterKeyProviders do not support providing encryption context on decrypt. + # If decrypting with a legacy MasterKeyProvider, you should manually verify + # that the encryption context used in the decrypt operation + # includes all key pairs from the encrypt operation. (The SDK can add pairs, so don't require an exact match.) + assert all( + pair in decrypted_header_mkp_using_mkp.encryption_context.items() + for pair in encrypted_header_mkp.encryption_context.items() + ) + assert decrypted_ciphertext_mkp_using_keyring == decrypted_ciphertext_mkp_using_mkp \ and decrypted_ciphertext_mkp_using_keyring == EXAMPLE_DATA, \ "Decrypted outputs using keyring and master key provider are not the same" diff --git a/examples/src/migration/migration_raw_aes_key_example.py b/examples/src/migration/migration_raw_aes_key_example.py index 772f83cf5..4bd15d1f9 100644 --- a/examples/src/migration/migration_raw_aes_key_example.py +++ b/examples/src/migration/migration_raw_aes_key_example.py @@ -156,14 +156,14 @@ def migration_raw_aes_key(): raw_aes_master_key_provider = create_key_provider() # 2a. Encrypt EXAMPLE_DATA using Raw AES Keyring - ciphertext_keyring, _ = client.encrypt( + ciphertext_keyring, encrypted_header_keyring = client.encrypt( source=EXAMPLE_DATA, keyring=raw_aes_keyring, encryption_context=DEFAULT_ENCRYPTION_CONTEXT ) # 2b. Encrypt EXAMPLE_DATA using Raw AES Master Key Provider - ciphertext_mkp, _ = client.encrypt( + ciphertext_mkp, encrypted_header_mkp = client.encrypt( source=EXAMPLE_DATA, key_provider=raw_aes_master_key_provider, encryption_context=DEFAULT_ENCRYPTION_CONTEXT @@ -178,14 +178,25 @@ def migration_raw_aes_key(): # resulting plaintext is the same and also equal to EXAMPLE_DATA decrypted_ciphertext_keyring_using_keyring, _ = client.decrypt( source=ciphertext_keyring, - keyring=raw_aes_keyring + keyring=raw_aes_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=DEFAULT_ENCRYPTION_CONTEXT, ) - decrypted_ciphertext_keyring_using_mkp, _ = client.decrypt( + decrypted_ciphertext_keyring_using_mkp, decrypted_header_keyring_using_mkp = client.decrypt( source=ciphertext_keyring, key_provider=raw_aes_master_key_provider ) + # Legacy MasterKeyProviders do not support providing encryption context on decrypt. + # If decrypting with a legacy MasterKeyProvider, you should manually verify + # that the encryption context used in the decrypt operation + # includes all key pairs from the encrypt operation. (The SDK can add pairs, so don't require an exact match.) + assert all( + pair in decrypted_header_keyring_using_mkp.encryption_context.items() + for pair in encrypted_header_keyring.encryption_context.items() + ) + assert decrypted_ciphertext_keyring_using_keyring == decrypted_ciphertext_keyring_using_mkp \ and decrypted_ciphertext_keyring_using_keyring == EXAMPLE_DATA, \ "Decrypted outputs using keyring and master key provider are not the same" @@ -194,14 +205,25 @@ def migration_raw_aes_key(): # resulting plaintext is the same and also equal to EXAMPLE_DATA decrypted_ciphertext_mkp_using_keyring, _ = client.decrypt( source=ciphertext_mkp, - keyring=raw_aes_keyring + keyring=raw_aes_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=DEFAULT_ENCRYPTION_CONTEXT, ) - decrypted_ciphertext_mkp_using_mkp, _ = client.decrypt( + decrypted_ciphertext_mkp_using_mkp, decrypted_header_mkp_using_mkp = client.decrypt( source=ciphertext_mkp, key_provider=raw_aes_master_key_provider ) + # Legacy MasterKeyProviders do not support providing encryption context on decrypt. + # If decrypting with a legacy MasterKeyProvider, you should manually verify + # that the encryption context used in the decrypt operation + # includes all key pairs from the encrypt operation. (The SDK can add pairs, so don't require an exact match.) + assert all( + pair in decrypted_header_mkp_using_mkp.encryption_context.items() + for pair in encrypted_header_mkp.encryption_context.items() + ) + assert decrypted_ciphertext_mkp_using_keyring == decrypted_ciphertext_mkp_using_mkp \ and decrypted_ciphertext_mkp_using_keyring == EXAMPLE_DATA, \ "Decrypted outputs using keyring and master key provider are not the same" diff --git a/examples/src/migration/migration_raw_rsa_key_example.py b/examples/src/migration/migration_raw_rsa_key_example.py index 7c6020a53..22c9512ec 100644 --- a/examples/src/migration/migration_raw_rsa_key_example.py +++ b/examples/src/migration/migration_raw_rsa_key_example.py @@ -208,14 +208,14 @@ def migration_raw_rsa_key( raw_rsa_master_key_provider = create_key_provider() # 2a. Encrypt EXAMPLE_DATA using Raw RSA Keyring - ciphertext_keyring, _ = client.encrypt( + ciphertext_keyring, encrypted_header_keyring = client.encrypt( source=EXAMPLE_DATA, keyring=raw_rsa_keyring, encryption_context=DEFAULT_ENCRYPTION_CONTEXT ) # 2b. Encrypt EXAMPLE_DATA using Raw RSA Master Key Provider - ciphertext_mkp, _ = client.encrypt( + ciphertext_mkp, encrypted_header_mkp = client.encrypt( source=EXAMPLE_DATA, key_provider=raw_rsa_master_key_provider, encryption_context=DEFAULT_ENCRYPTION_CONTEXT @@ -230,14 +230,25 @@ def migration_raw_rsa_key( # resulting plaintext is the same and also equal to EXAMPLE_DATA decrypted_ciphertext_keyring_using_keyring, _ = client.decrypt( source=ciphertext_keyring, - keyring=raw_rsa_keyring + keyring=raw_rsa_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=DEFAULT_ENCRYPTION_CONTEXT, ) - decrypted_ciphertext_keyring_using_mkp, _ = client.decrypt( + decrypted_ciphertext_keyring_using_mkp, decrypted_header_keyring_using_mkp = client.decrypt( source=ciphertext_keyring, key_provider=raw_rsa_master_key_provider ) + # Legacy MasterKeyProviders do not support providing encryption context on decrypt. + # If decrypting with a legacy MasterKeyProvider, you should manually verify + # that the encryption context used in the decrypt operation + # includes all key pairs from the encrypt operation. (The SDK can add pairs, so don't require an exact match.) + assert all( + pair in decrypted_header_keyring_using_mkp.encryption_context.items() + for pair in encrypted_header_keyring.encryption_context.items() + ) + assert decrypted_ciphertext_keyring_using_keyring == decrypted_ciphertext_keyring_using_mkp \ and decrypted_ciphertext_keyring_using_keyring == EXAMPLE_DATA, \ "Decrypted outputs using keyring and master key provider are not the same" @@ -246,14 +257,25 @@ def migration_raw_rsa_key( # resulting plaintext is the same and also equal to EXAMPLE_DATA decrypted_ciphertext_mkp_using_keyring, _ = client.decrypt( source=ciphertext_mkp, - keyring=raw_rsa_keyring + keyring=raw_rsa_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=DEFAULT_ENCRYPTION_CONTEXT, ) - decrypted_ciphertext_mkp_using_mkp, _ = client.decrypt( + decrypted_ciphertext_mkp_using_mkp, decrypted_header_mkp_using_mkp = client.decrypt( source=ciphertext_mkp, key_provider=raw_rsa_master_key_provider ) + # Legacy MasterKeyProviders do not support providing encryption context on decrypt. + # If decrypting with a legacy MasterKeyProvider, you should manually verify + # that the encryption context used in the decrypt operation + # includes all key pairs from the encrypt operation. (The SDK can add pairs, so don't require an exact match.) + assert all( + pair in decrypted_header_mkp_using_mkp.encryption_context.items() + for pair in encrypted_header_mkp.encryption_context.items() + ) + assert decrypted_ciphertext_mkp_using_keyring == decrypted_ciphertext_mkp_using_mkp \ and decrypted_ciphertext_mkp_using_keyring == EXAMPLE_DATA, \ "Decrypted outputs using keyring and master key provider are not the same" diff --git a/examples/src/migration/migration_set_commitment_policy_example.py b/examples/src/migration/migration_set_commitment_policy_example.py index 3851df0e2..5598e9575 100644 --- a/examples/src/migration/migration_set_commitment_policy_example.py +++ b/examples/src/migration/migration_set_commitment_policy_example.py @@ -105,18 +105,14 @@ 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, + # Provide the encryption context that was 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" diff --git a/examples/src/multi_keyring_example.py b/examples/src/multi_keyring_example.py index 20af7ba81..f55b2aeca 100644 --- a/examples/src/multi_keyring_example.py +++ b/examples/src/multi_keyring_example.py @@ -164,7 +164,9 @@ def encrypt_and_decrypt_with_keyring( # 10a. Decrypt your encrypted data using the same multi_keyring you used on encrypt. plaintext_bytes_multi_keyring, _ = client.decrypt( source=ciphertext, - keyring=multi_keyring + keyring=multi_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=encryption_context, ) # 10b. Demonstrate that the decrypted plaintext is identical to the original plaintext. @@ -182,7 +184,9 @@ def encrypt_and_decrypt_with_keyring( # 11a. Decrypt your encrypted data using the kms_keyring. plaintext_bytes_kms_keyring, _ = client.decrypt( source=ciphertext, - keyring=kms_keyring + keyring=kms_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=encryption_context, ) # 11b. Demonstrate that the decrypted plaintext is identical to the original plaintext. @@ -197,7 +201,9 @@ def encrypt_and_decrypt_with_keyring( # 12a. Decrypt your encrypted data using the raw_aes_keyring. plaintext_bytes_raw_aes_keyring, _ = client.decrypt( source=ciphertext, - keyring=raw_aes_keyring + keyring=raw_aes_keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=encryption_context, ) # 12b. Demonstrate that the decrypted plaintext is identical to the original plaintext. diff --git a/examples/src/multithreading/__init__.py b/examples/src/multithreading/__init__.py index 32210a0ab..4fdad58fd 100644 --- a/examples/src/multithreading/__init__.py +++ b/examples/src/multithreading/__init__.py @@ -42,7 +42,9 @@ def encrypt_and_decrypt_with_keyring( decrypted_plaintext_data, _ = client.decrypt( source=ciphertext_data, - keyring=keyring + keyring=keyring, + # Provide the encryption context that was supplied to the encrypt method + encryption_context=encryption_context, ) return decrypted_plaintext_data diff --git a/examples/src/raw_aes_keyring_example.py b/examples/src/raw_aes_keyring_example.py index ab9603af6..8d6dd9513 100644 --- a/examples/src/raw_aes_keyring_example.py +++ b/examples/src/raw_aes_keyring_example.py @@ -107,18 +107,14 @@ def encrypt_and_decrypt_with_keyring(): "Ciphertext and plaintext data are the same. Invalid encryption" # 8. 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=raw_aes_keyring + keyring=raw_aes_keyring, + # Provide the encryption context that was 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" diff --git a/examples/src/raw_rsa_keyring_example.py b/examples/src/raw_rsa_keyring_example.py index 1200a7c72..3a47dfe8e 100644 --- a/examples/src/raw_rsa_keyring_example.py +++ b/examples/src/raw_rsa_keyring_example.py @@ -205,18 +205,14 @@ def encrypt_and_decrypt_with_keyring(public_key_file_name=None, private_key_file "Ciphertext and plaintext data are the same. Invalid encryption" # 6. 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=raw_rsa_keyring + keyring=raw_rsa_keyring, + # Provide the encryption context that was 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" @@ -225,18 +221,21 @@ def encrypt_and_decrypt_with_keyring(public_key_file_name=None, private_key_file # decryption of the original ciphertext is not possible with a different keyring (Bob's). # (This is an example for demonstration; you do not need to do this in your own code.) - # 9. Create a new Raw RSA keyring for Bob + # 8. Create a new Raw RSA keyring for Bob # Generate new keys public_key_bob, private_key_bob = generate_rsa_keys() # Create the keyring raw_rsa_keyring_bob = create_rsa_keyring(public_key=public_key_bob, private_key=private_key_bob) - # 10. Test decrypt for the original ciphertext using raw_rsa_keyring_bob + # 9. Test decrypt for the original ciphertext using raw_rsa_keyring_bob try: plaintext_bytes_bob, _ = client.decrypt( # pylint: disable=unused-variable source=ciphertext, - keyring=raw_rsa_keyring_bob + keyring=raw_rsa_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("client.decrypt should throw an error of type AWSEncryptionSDKClientError!") diff --git a/examples/src/set_encryption_algorithm_suite_example.py b/examples/src/set_encryption_algorithm_suite_example.py index 75eaee85a..bbe5be58a 100644 --- a/examples/src/set_encryption_algorithm_suite_example.py +++ b/examples/src/set_encryption_algorithm_suite_example.py @@ -128,18 +128,14 @@ def encrypt_and_decrypt_with_keyring(): "Ciphertext and plaintext data are the same. Invalid encryption" # 8. 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=raw_aes_keyring + keyring=raw_aes_keyring, + # Provide the encryption context that was 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"