From 1d684656fdbd006774fdf03755e0b093e7698c02 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Mon, 20 Jul 2020 15:25:34 -0700 Subject: [PATCH 1/3] docs: add API usage examples templates --- .../templates/api/change-algorithm-suite.md | 133 +++++++++++++++++ examples/templates/api/one-step-in-memory.md | 114 +++++++++++++++ .../templates/api/streaming-file-to-file.md | 138 ++++++++++++++++++ examples/templates/api/streaming-in-memory.md | 131 +++++++++++++++++ 4 files changed, 516 insertions(+) create mode 100644 examples/templates/api/change-algorithm-suite.md create mode 100644 examples/templates/api/one-step-in-memory.md create mode 100644 examples/templates/api/streaming-file-to-file.md create mode 100644 examples/templates/api/streaming-in-memory.md diff --git a/examples/templates/api/change-algorithm-suite.md b/examples/templates/api/change-algorithm-suite.md new file mode 100644 index 00000000..91db1426 --- /dev/null +++ b/examples/templates/api/change-algorithm-suite.md @@ -0,0 +1,133 @@ +[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." +[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" + +# Changing the algorithm suite example + +Implementations of this example MUST follow the rules defined in +[Example Templates](../../../examples.md#example-templates). + +## Implementations + +- [Python (DEV)]() +- [Java (DEV)]() + +## Definitions + +### Conventions used in this document + +The key words +"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" +in this document are to be interpreted as described in +[RFC 2119](https://tools.ietf.org/html/rfc2119). + +## Header + +```python +# This example shows how to specify an algorithm suite +# when using the one-step encrypt and decrypt APIs. +# +# In this example, we use an AWS KMS customer master key (CMK), +# but you can use other key management options with the AWS Encryption SDK. +# For examples that demonstrate how to use other key management configurations, +# see the ``keyring`` and ``master_key_provider`` directories. +# +# The default algorithm suite includes a message-level signature +# that protects you from an attacker who has *decrypt* but not *encrypt* capability +# for a wrapping key that you used when encrypting a message +# under multiple wrapping keys. +# +# However, if all of your readers and writers have the same permissions, +# then this additional protection does not always add value. +# This example shows you how to select another algorithm suite +# that has all of the other properties of the default suite +# but does not include a message-level signature. +``` + +## Summary + +```python +# Demonstrate requesting a specific algorithm suite through the one-step encrypt/decrypt APIs. +``` + +## Inputs + +- **source plaintext** : + Plaintext to encrypt +- **AWS KMS CMK** : + The ARN of an AWS KMS CMK that protects data keys + +## Steps + +1. Define encryption context. + + ```python + # Prepare your encryption context. + # Remember that your encryption context is NOT SECRET. + # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context + encryption_context = { + "encryption": "context", + "is not": "secret", + "but adds": "useful metadata", + "that can help you": "be confident that", + "the data you are handling": "is what you think it is", + } + ``` + +1. Create keyring. + + ```python + # Create the keyring that determines how your data keys are protected. + keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) + ``` + +1. Encrypt plaintext data. + + ```python + # Encrypt your plaintext data. + ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( + source=source_plaintext, + encryption_context=encryption_context, + keyring=keyring, + # Here we can specify the algorithm suite that we want to use. + algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + ) + ``` + +1. Compare ciphertext to plaintext. + + ```python + # Demonstrate that the ciphertext and plaintext are different. + assert ciphertext != source_plaintext + ``` + +1. Decrypt encrypted data. + + ```python + # Decrypt your encrypted data using the same keyring you used on encrypt. + # + # You do not need to specify the encryption context on decrypt + # because the header of the encrypted message includes the encryption context. + # + # You do not need to specify the algorithm suite on decrypt + # because the header message includes the algorithm suite identifier. + decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring) + ``` + +1. Compare the decrypted plaintext and original plaintext. + + ```python + # Demonstrate that the decrypted plaintext is identical to the original plaintext. + assert decrypted == source_plaintext + ``` + +1. Verify the encryption context. + + ```python + # Verify that the encryption context used in the decrypt operation includes + # the encryption context that you specified when encrypting. + # The AWS Encryption SDK can add pairs, so don't require an exact match. + # + # In production, always use a meaningful encryption context. + assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items()) + ``` diff --git a/examples/templates/api/one-step-in-memory.md b/examples/templates/api/one-step-in-memory.md new file mode 100644 index 00000000..204ff9fe --- /dev/null +++ b/examples/templates/api/one-step-in-memory.md @@ -0,0 +1,114 @@ +[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." +[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" + +# Basic use of one-step APIs example + +Implementations of this example MUST follow the rules defined in +[Example Templates](../../../examples.md#example-templates). + +## Implementations + +- [Python (DEV)]() +- [Java (DEV)]() + +## Definitions + +### Conventions used in this document + +The key words +"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" +in this document are to be interpreted as described in +[RFC 2119](https://tools.ietf.org/html/rfc2119). + +## Header + +```python +# This example shows how to use the one-step encrypt and decrypt APIs. +# +# In this example, we use an AWS KMS customer master key (CMK), +# but you can use other key management options with the AWS Encryption SDK. +# For examples that demonstrate how to use other key management configurations, +# see the ``keyring`` and ``master_key_provider`` directories. +``` + +## Summary + +```python +# Demonstrate an encrypt/decrypt cycle using the one-step encrypt/decrypt APIs. +``` + +## Inputs + +- **source plaintext** : + Plaintext to encrypt +- **AWS KMS CMK** : + The ARN of an AWS KMS CMK that protects data keys + +## Steps + +1. Define encryption context. + + ```python + # Prepare your encryption context. + # Remember that your encryption context is NOT SECRET. + # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context + encryption_context = { + "encryption": "context", + "is not": "secret", + "but adds": "useful metadata", + "that can help you": "be confident that", + "the data you are handling": "is what you think it is", + } + ``` + +1. Create keyring. + + ```python + # Create the keyring that determines how your data keys are protected. + keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) + ``` + +1. Encrypt plaintext data. + + ```python + # Encrypt your plaintext data. + ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( + source=source_plaintext, encryption_context=encryption_context, keyring=keyring + ) + ``` + +1. Compare ciphertext to plaintext. + + ```python + # Demonstrate that the ciphertext and plaintext are different. + assert ciphertext != source_plaintext + ``` + +1. Decrypt encrypted data. + + ```python + # Decrypt your encrypted data using the same keyring you used on encrypt. + # + # You do not need to specify the encryption context on decrypt + # because the header of the encrypted message includes the encryption context. + decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring) + ``` + +1. Compare the decrypted plaintext and original plaintext. + + ```python + # Demonstrate that the decrypted plaintext is identical to the original plaintext. + assert decrypted == source_plaintext + ``` + +1. Verify the encryption context. + + ```python + # Verify that the encryption context used in the decrypt operation includes + # the encryption context that you specified when encrypting. + # The AWS Encryption SDK can add pairs, so don't require an exact match. + # + # In production, always use a meaningful encryption context. + assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items()) + ``` diff --git a/examples/templates/api/streaming-file-to-file.md b/examples/templates/api/streaming-file-to-file.md new file mode 100644 index 00000000..38f547c7 --- /dev/null +++ b/examples/templates/api/streaming-file-to-file.md @@ -0,0 +1,138 @@ +[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." +[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" + +# Basic use of stream APIs example using files + +Implementations of this example MUST follow the rules defined in +[Example Templates](../../../examples.md#example-templates). + +## Implementations + +- [Python (DEV)]() +- [Java (DEV)]() + +## Definitions + +### Conventions used in this document + +The key words +"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" +in this document are to be interpreted as described in +[RFC 2119](https://tools.ietf.org/html/rfc2119). + +## Header + +```python +# This example shows how to use the streaming encrypt and decrypt APIs when working with files. +# +# One benefit of using the streaming API is that +# we can check the encryption context in the header before we start decrypting. +# +# In this example, we use an AWS KMS customer master key (CMK), +# but you can use other key management options with the AWS Encryption SDK. +# For examples that demonstrate how to use other key management configurations, +# see the ``keyring`` and ``master_key_provider`` directories. +``` + +## Summary + +```python +# Demonstrate an encrypt/decrypt cycle using the streaming encrypt/decrypt APIs with files. +``` + +## Inputs + +- **source plaintext filename** : + Path to plaintext file to encrypt +- **AWS KMS CMK** : + The ARN of an AWS KMS CMK that protects data keys + +## Steps + +1. Define file targets. + + ```python + # We assume that you can also write to the directory containing the plaintext file, + # so that is where we will put all of the results. + ciphertext_filename = source_plaintext_filename + ".encrypted" + decrypted_filename = ciphertext_filename + ".decrypted" + ``` + +1. Define encryption context. + + ```python + # Prepare your encryption context. + # Remember that your encryption context is NOT SECRET. + # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context + encryption_context = { + "encryption": "context", + "is not": "secret", + "but adds": "useful metadata", + "that can help you": "be confident that", + "the data you are handling": "is what you think it is", + } + ``` + +1. Create keyring. + + ```python + # Create the keyring that determines how your data keys are protected. + keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) + ``` + +1. Encrypt plaintext data. + + ```python + # Open the files you want to work with. + with open(source_plaintext_filename, "rb") as plaintext, open(ciphertext_filename, "wb") as ciphertext: + # The streaming API provides a context manager. + # You can read from it just as you read from a file. + with aws_encryption_sdk.stream( + mode="encrypt", source=plaintext, encryption_context=encryption_context, keyring=keyring + ) as encryptor: + # Iterate through the segments in the context manager + # and write the results to the ciphertext. + for segment in encryptor: + ciphertext.write(segment) + ``` + +1. Compare ciphertext to plaintext. + + ```python + # Demonstrate that the ciphertext and plaintext are different. + assert not filecmp.cmp(source_plaintext_filename, ciphertext_filename) + ``` + +1. Decrypt encrypted data, + verifying the encryption context before decrypting body. + + ```python + # Open the files you want to work with. + with open(ciphertext_filename, "rb") as ciphertext, open(decrypted_filename, "wb") as decrypted: + # Decrypt your encrypted data using the same keyring you used on encrypt. + # + # You do not need to specify the encryption context on decrypt + # because the header of the encrypted message includes the encryption context. + with aws_encryption_sdk.stream(mode="decrypt", source=ciphertext, keyring=keyring) as decryptor: + # Check the encryption context in the header before we start decrypting. + # + # Verify that the encryption context used in the decrypt operation includes + # the encryption context that you specified when encrypting. + # The AWS Encryption SDK can add pairs, so don't require an exact match. + # + # In production, always use a meaningful encryption context. + assert set(encryption_context.items()) <= set(decryptor.header.encryption_context.items()) + + # Now that we are more confident that we will decrypt the right message, + # we can start decrypting. + for segment in decryptor: + decrypted.write(segment) + ``` + +1. Compare the decrypted plaintext and original plaintext. + + ```python + # Demonstrate that the decrypted plaintext is identical to the original plaintext. + assert filecmp.cmp(source_plaintext_filename, decrypted_filename) + ``` diff --git a/examples/templates/api/streaming-in-memory.md b/examples/templates/api/streaming-in-memory.md new file mode 100644 index 00000000..a4ba6977 --- /dev/null +++ b/examples/templates/api/streaming-in-memory.md @@ -0,0 +1,131 @@ +[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." +[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" + +# Basic use of stream APIs example using an in-memory stream + +Implementations of this example MUST follow the rules defined in +[Example Templates](../../../examples.md#example-templates). + +## Implementations + +- [Python (DEV)]() +- [Java (DEV)]() + +## Definitions + +### Conventions used in this document + +The key words +"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" +in this document are to be interpreted as described in +[RFC 2119](https://tools.ietf.org/html/rfc2119). + +## Header + +```python +# This example shows how to use the streaming encrypt and decrypt APIs on data in memory. +# +# One benefit of using the streaming API is that +# we can check the encryption context in the header before we start decrypting. +# +# In this example, we use an AWS KMS customer master key (CMK), +# but you can use other key management options with the AWS Encryption SDK. +# For examples that demonstrate how to use other key management configurations, +# see the ``keyring`` and ``master_key_provider`` directories. +``` + +## Summary + +```python +# Demonstrate an encrypt/decrypt cycle using the streaming encrypt/decrypt APIs in-memory. +``` + +## Inputs + +- **source plaintext** : + Plaintext to encrypt +- **AWS KMS CMK** : + The ARN of an AWS KMS CMK that protects data keys + +## Steps + +1. Define encryption context. + + ```python + # Prepare your encryption context. + # Remember that your encryption context is NOT SECRET. + # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context + encryption_context = { + "encryption": "context", + "is not": "secret", + "but adds": "useful metadata", + "that can help you": "be confident that", + "the data you are handling": "is what you think it is", + } + ``` + +1. Create keyring. + + ```python + # Create the keyring that determines how your data keys are protected. + keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) + ``` + +1. Encrypt plaintext data. + + ```python + ciphertext = io.BytesIO() + + # The streaming API provides a context manager. + # You can read from it just as you read from a file. + with aws_encryption_sdk.stream( + mode="encrypt", source=source_plaintext, encryption_context=encryption_context, keyring=keyring + ) as encryptor: + # Iterate through the segments in the context manager + # and write the results to the ciphertext. + for segment in encryptor: + ciphertext.write(segment) + ``` + +1. Compare ciphertext to plaintext. + + ```python + # Demonstrate that the ciphertext and plaintext are different. + assert ciphertext.getvalue() != source_plaintext + ``` + +1. Decrypt encrypted data, + verifying the encryption context before decrypting body. + + ```python + # Reset the ciphertext stream position so that we can read from the beginning. + ciphertext.seek(0) + + # Decrypt your encrypted data using the same keyring you used on encrypt. + # + # You do not need to specify the encryption context on decrypt + # because the header of the encrypted message includes the encryption context. + decrypted = io.BytesIO() + with aws_encryption_sdk.stream(mode="decrypt", source=ciphertext, keyring=keyring) as decryptor: + # Check the encryption context in the header before we start decrypting. + # + # Verify that the encryption context used in the decrypt operation includes + # the encryption context that you specified when encrypting. + # The AWS Encryption SDK can add pairs, so don't require an exact match. + # + # In production, always use a meaningful encryption context. + assert set(encryption_context.items()) <= set(decryptor.header.encryption_context.items()) + + # Now that we are more confident that we will decrypt the right message, + # we can start decrypting. + for segment in decryptor: + decrypted.write(segment) + ``` + +1. Compare the decrypted plaintext and original plaintext. + + ```python + # Demonstrate that the decrypted plaintext is identical to the original plaintext. + assert decrypted.getvalue() == source_plaintext + ``` From 7936142cf9bdc59391e787dd8929da625b4fdc4b Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Mon, 20 Jul 2020 15:30:13 -0700 Subject: [PATCH 2/3] docs: add links to implementations --- examples/templates/api/change-algorithm-suite.md | 4 ++-- examples/templates/api/one-step-in-memory.md | 4 ++-- examples/templates/api/streaming-file-to-file.md | 4 ++-- examples/templates/api/streaming-in-memory.md | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/templates/api/change-algorithm-suite.md b/examples/templates/api/change-algorithm-suite.md index 91db1426..077956a7 100644 --- a/examples/templates/api/change-algorithm-suite.md +++ b/examples/templates/api/change-algorithm-suite.md @@ -8,8 +8,8 @@ Implementations of this example MUST follow the rules defined in ## Implementations -- [Python (DEV)]() -- [Java (DEV)]() +- [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/onestep_unsigned.py) +- [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java) ## Definitions diff --git a/examples/templates/api/one-step-in-memory.md b/examples/templates/api/one-step-in-memory.md index 204ff9fe..f1bb429d 100644 --- a/examples/templates/api/one-step-in-memory.md +++ b/examples/templates/api/one-step-in-memory.md @@ -8,8 +8,8 @@ Implementations of this example MUST follow the rules defined in ## Implementations -- [Python (DEV)]() -- [Java (DEV)]() +- [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/onestep_defaults.py) +- [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java) ## Definitions diff --git a/examples/templates/api/streaming-file-to-file.md b/examples/templates/api/streaming-file-to-file.md index 38f547c7..ac9c162c 100644 --- a/examples/templates/api/streaming-file-to-file.md +++ b/examples/templates/api/streaming-file-to-file.md @@ -8,8 +8,8 @@ Implementations of this example MUST follow the rules defined in ## Implementations -- [Python (DEV)]() -- [Java (DEV)]() +- [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/file_streaming_defaults.py) +- [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java) ## Definitions diff --git a/examples/templates/api/streaming-in-memory.md b/examples/templates/api/streaming-in-memory.md index a4ba6977..cbf25304 100644 --- a/examples/templates/api/streaming-in-memory.md +++ b/examples/templates/api/streaming-in-memory.md @@ -8,8 +8,8 @@ Implementations of this example MUST follow the rules defined in ## Implementations -- [Python (DEV)]() -- [Java (DEV)]() +- [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/in_memory_streaming_defaults.py) +- [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java) ## Definitions From 49593d6991c75254c2d5a0805f3b08b57aa4ba66 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Thu, 30 Jul 2020 17:54:08 -0700 Subject: [PATCH 3/3] docs: remove code from API examples templates and remove redundant file example --- .../templates/api/change-algorithm-suite.md | 32 ++-- examples/templates/api/one-step-in-memory.md | 26 ++-- .../templates/api/streaming-file-to-file.md | 138 ------------------ examples/templates/api/streaming-in-memory.md | 68 ++++----- 4 files changed, 45 insertions(+), 219 deletions(-) delete mode 100644 examples/templates/api/streaming-file-to-file.md diff --git a/examples/templates/api/change-algorithm-suite.md b/examples/templates/api/change-algorithm-suite.md index 077956a7..449c6acf 100644 --- a/examples/templates/api/change-algorithm-suite.md +++ b/examples/templates/api/change-algorithm-suite.md @@ -23,7 +23,7 @@ in this document are to be interpreted as described in ## Header -```python +``` # This example shows how to specify an algorithm suite # when using the one-step encrypt and decrypt APIs. # @@ -46,7 +46,7 @@ in this document are to be interpreted as described in ## Summary -```python +``` # Demonstrate requesting a specific algorithm suite through the one-step encrypt/decrypt APIs. ``` @@ -61,7 +61,7 @@ in this document are to be interpreted as described in 1. Define encryption context. - ```python + ``` # Prepare your encryption context. # Remember that your encryption context is NOT SECRET. # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context @@ -76,34 +76,27 @@ in this document are to be interpreted as described in 1. Create keyring. - ```python + ``` # Create the keyring that determines how your data keys are protected. - keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) ``` 1. Encrypt plaintext data. - ```python + ``` # Encrypt your plaintext data. - ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( - source=source_plaintext, - encryption_context=encryption_context, - keyring=keyring, - # Here we can specify the algorithm suite that we want to use. - algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, - ) + # + # Specifically request the AES_256_GCM_IV12_TAG16_HKDF_SHA256 algorithm suite. ``` 1. Compare ciphertext to plaintext. - ```python + ``` # Demonstrate that the ciphertext and plaintext are different. - assert ciphertext != source_plaintext ``` 1. Decrypt encrypted data. - ```python + ``` # Decrypt your encrypted data using the same keyring you used on encrypt. # # You do not need to specify the encryption context on decrypt @@ -111,23 +104,20 @@ in this document are to be interpreted as described in # # You do not need to specify the algorithm suite on decrypt # because the header message includes the algorithm suite identifier. - decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring) ``` 1. Compare the decrypted plaintext and original plaintext. - ```python + ``` # Demonstrate that the decrypted plaintext is identical to the original plaintext. - assert decrypted == source_plaintext ``` 1. Verify the encryption context. - ```python + ``` # Verify that the encryption context used in the decrypt operation includes # the encryption context that you specified when encrypting. # The AWS Encryption SDK can add pairs, so don't require an exact match. # # In production, always use a meaningful encryption context. - assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items()) ``` diff --git a/examples/templates/api/one-step-in-memory.md b/examples/templates/api/one-step-in-memory.md index f1bb429d..4d572591 100644 --- a/examples/templates/api/one-step-in-memory.md +++ b/examples/templates/api/one-step-in-memory.md @@ -23,7 +23,7 @@ in this document are to be interpreted as described in ## Header -```python +``` # This example shows how to use the one-step encrypt and decrypt APIs. # # In this example, we use an AWS KMS customer master key (CMK), @@ -34,7 +34,7 @@ in this document are to be interpreted as described in ## Summary -```python +``` # Demonstrate an encrypt/decrypt cycle using the one-step encrypt/decrypt APIs. ``` @@ -49,7 +49,7 @@ in this document are to be interpreted as described in 1. Define encryption context. - ```python + ``` # Prepare your encryption context. # Remember that your encryption context is NOT SECRET. # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context @@ -64,51 +64,43 @@ in this document are to be interpreted as described in 1. Create keyring. - ```python + ``` # Create the keyring that determines how your data keys are protected. - keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) ``` 1. Encrypt plaintext data. - ```python + ``` # Encrypt your plaintext data. - ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( - source=source_plaintext, encryption_context=encryption_context, keyring=keyring - ) ``` 1. Compare ciphertext to plaintext. - ```python + ``` # Demonstrate that the ciphertext and plaintext are different. - assert ciphertext != source_plaintext ``` 1. Decrypt encrypted data. - ```python + ``` # Decrypt your encrypted data using the same keyring you used on encrypt. # # You do not need to specify the encryption context on decrypt # because the header of the encrypted message includes the encryption context. - decrypted, decrypt_header = aws_encryption_sdk.decrypt(source=ciphertext, keyring=keyring) ``` 1. Compare the decrypted plaintext and original plaintext. - ```python + ``` # Demonstrate that the decrypted plaintext is identical to the original plaintext. - assert decrypted == source_plaintext ``` 1. Verify the encryption context. - ```python + ``` # Verify that the encryption context used in the decrypt operation includes # the encryption context that you specified when encrypting. # The AWS Encryption SDK can add pairs, so don't require an exact match. # # In production, always use a meaningful encryption context. - assert set(encryption_context.items()) <= set(decrypt_header.encryption_context.items()) ``` diff --git a/examples/templates/api/streaming-file-to-file.md b/examples/templates/api/streaming-file-to-file.md deleted file mode 100644 index ac9c162c..00000000 --- a/examples/templates/api/streaming-file-to-file.md +++ /dev/null @@ -1,138 +0,0 @@ -[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." -[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" - -# Basic use of stream APIs example using files - -Implementations of this example MUST follow the rules defined in -[Example Templates](../../../examples.md#example-templates). - -## Implementations - -- [Python (DEV)](https://github.com/aws/aws-encryption-sdk-python/blob/keyring/examples/src/file_streaming_defaults.py) -- [Java (DEV)](https://github.com/aws/aws-encryption-sdk-java/blob/keyring/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java) - -## Definitions - -### Conventions used in this document - -The key words -"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", -"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" -in this document are to be interpreted as described in -[RFC 2119](https://tools.ietf.org/html/rfc2119). - -## Header - -```python -# This example shows how to use the streaming encrypt and decrypt APIs when working with files. -# -# One benefit of using the streaming API is that -# we can check the encryption context in the header before we start decrypting. -# -# In this example, we use an AWS KMS customer master key (CMK), -# but you can use other key management options with the AWS Encryption SDK. -# For examples that demonstrate how to use other key management configurations, -# see the ``keyring`` and ``master_key_provider`` directories. -``` - -## Summary - -```python -# Demonstrate an encrypt/decrypt cycle using the streaming encrypt/decrypt APIs with files. -``` - -## Inputs - -- **source plaintext filename** : - Path to plaintext file to encrypt -- **AWS KMS CMK** : - The ARN of an AWS KMS CMK that protects data keys - -## Steps - -1. Define file targets. - - ```python - # We assume that you can also write to the directory containing the plaintext file, - # so that is where we will put all of the results. - ciphertext_filename = source_plaintext_filename + ".encrypted" - decrypted_filename = ciphertext_filename + ".decrypted" - ``` - -1. Define encryption context. - - ```python - # Prepare your encryption context. - # Remember that your encryption context is NOT SECRET. - # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context - encryption_context = { - "encryption": "context", - "is not": "secret", - "but adds": "useful metadata", - "that can help you": "be confident that", - "the data you are handling": "is what you think it is", - } - ``` - -1. Create keyring. - - ```python - # Create the keyring that determines how your data keys are protected. - keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) - ``` - -1. Encrypt plaintext data. - - ```python - # Open the files you want to work with. - with open(source_plaintext_filename, "rb") as plaintext, open(ciphertext_filename, "wb") as ciphertext: - # The streaming API provides a context manager. - # You can read from it just as you read from a file. - with aws_encryption_sdk.stream( - mode="encrypt", source=plaintext, encryption_context=encryption_context, keyring=keyring - ) as encryptor: - # Iterate through the segments in the context manager - # and write the results to the ciphertext. - for segment in encryptor: - ciphertext.write(segment) - ``` - -1. Compare ciphertext to plaintext. - - ```python - # Demonstrate that the ciphertext and plaintext are different. - assert not filecmp.cmp(source_plaintext_filename, ciphertext_filename) - ``` - -1. Decrypt encrypted data, - verifying the encryption context before decrypting body. - - ```python - # Open the files you want to work with. - with open(ciphertext_filename, "rb") as ciphertext, open(decrypted_filename, "wb") as decrypted: - # Decrypt your encrypted data using the same keyring you used on encrypt. - # - # You do not need to specify the encryption context on decrypt - # because the header of the encrypted message includes the encryption context. - with aws_encryption_sdk.stream(mode="decrypt", source=ciphertext, keyring=keyring) as decryptor: - # Check the encryption context in the header before we start decrypting. - # - # Verify that the encryption context used in the decrypt operation includes - # the encryption context that you specified when encrypting. - # The AWS Encryption SDK can add pairs, so don't require an exact match. - # - # In production, always use a meaningful encryption context. - assert set(encryption_context.items()) <= set(decryptor.header.encryption_context.items()) - - # Now that we are more confident that we will decrypt the right message, - # we can start decrypting. - for segment in decryptor: - decrypted.write(segment) - ``` - -1. Compare the decrypted plaintext and original plaintext. - - ```python - # Demonstrate that the decrypted plaintext is identical to the original plaintext. - assert filecmp.cmp(source_plaintext_filename, decrypted_filename) - ``` diff --git a/examples/templates/api/streaming-in-memory.md b/examples/templates/api/streaming-in-memory.md index cbf25304..71d9bc40 100644 --- a/examples/templates/api/streaming-in-memory.md +++ b/examples/templates/api/streaming-in-memory.md @@ -23,7 +23,7 @@ in this document are to be interpreted as described in ## Header -```python +``` # This example shows how to use the streaming encrypt and decrypt APIs on data in memory. # # One benefit of using the streaming API is that @@ -37,7 +37,7 @@ in this document are to be interpreted as described in ## Summary -```python +``` # Demonstrate an encrypt/decrypt cycle using the streaming encrypt/decrypt APIs in-memory. ``` @@ -52,7 +52,7 @@ in this document are to be interpreted as described in 1. Define encryption context. - ```python + ``` # Prepare your encryption context. # Remember that your encryption context is NOT SECRET. # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context @@ -67,65 +67,47 @@ in this document are to be interpreted as described in 1. Create keyring. - ```python + ``` # Create the keyring that determines how your data keys are protected. - keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk) ``` 1. Encrypt plaintext data. - ```python - ciphertext = io.BytesIO() - - # The streaming API provides a context manager. - # You can read from it just as you read from a file. - with aws_encryption_sdk.stream( - mode="encrypt", source=source_plaintext, encryption_context=encryption_context, keyring=keyring - ) as encryptor: - # Iterate through the segments in the context manager - # and write the results to the ciphertext. - for segment in encryptor: - ciphertext.write(segment) + ``` + # Create a plaintext stream from the source plaintext. + ``` + + ``` + # Use the streaming encryption API to encrypt the plaintext. ``` 1. Compare ciphertext to plaintext. - ```python + ``` # Demonstrate that the ciphertext and plaintext are different. - assert ciphertext.getvalue() != source_plaintext ``` 1. Decrypt encrypted data, verifying the encryption context before decrypting body. - ```python - # Reset the ciphertext stream position so that we can read from the beginning. - ciphertext.seek(0) - - # Decrypt your encrypted data using the same keyring you used on encrypt. + ``` + # Open a decryption stream to decrypt the encrypted message. + # + # Before decrypting the plaintext, + # check the encryption context in the header. # - # You do not need to specify the encryption context on decrypt - # because the header of the encrypted message includes the encryption context. - decrypted = io.BytesIO() - with aws_encryption_sdk.stream(mode="decrypt", source=ciphertext, keyring=keyring) as decryptor: - # Check the encryption context in the header before we start decrypting. - # - # Verify that the encryption context used in the decrypt operation includes - # the encryption context that you specified when encrypting. - # The AWS Encryption SDK can add pairs, so don't require an exact match. - # - # In production, always use a meaningful encryption context. - assert set(encryption_context.items()) <= set(decryptor.header.encryption_context.items()) - - # Now that we are more confident that we will decrypt the right message, - # we can start decrypting. - for segment in decryptor: - decrypted.write(segment) + # Verify that the encryption context used in the decrypt operation includes + # the encryption context that you specified when encrypting. + # The AWS Encryption SDK can add pairs, so don't require an exact match. + # + # In production, always use a meaningful encryption context. + # + # Now that we are more confident that we will decrypt the right message, + # we can start decrypting. ``` 1. Compare the decrypted plaintext and original plaintext. - ```python + ``` # Demonstrate that the decrypted plaintext is identical to the original plaintext. - assert decrypted.getvalue() == source_plaintext ```