Skip to content
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

docs: add API usage examples templates #179

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
133 changes: 133 additions & 0 deletions examples/templates/api/change-algorithm-suite.md
Original file line number Diff line number Diff line change
@@ -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).
Copy link
Contributor

Choose a reason for hiding this comment

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

This applies here and in other documents in this PR.

I think this path isn't resolving properly.

Copy link
Contributor

@acioc acioc Jul 20, 2020

Choose a reason for hiding this comment

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

I think these might just need to be

[Example Templates](../../examples.md#example-templates).

Copy link
Member Author

Choose a reason for hiding this comment

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

doh; that is correct; I copy-pasted that from the raw keyring examples and they have at least one extra directory layer x_x


## Implementations

- [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

### 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.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have these directories in the spec/will we? If not, should we link to something else here?

This applies to this doc page and others in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, for master_key_provider not all implementations support this.
We may want to try and remove it?

#
# The default algorithm suite includes a message-level signature
Copy link
Contributor

Choose a reason for hiding this comment

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

If the "default algorithm suite" ever changes, how are we going to find all these places to update them?

# 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
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be good to link to AWS docs (for ARN)? Either way, might also be good to note if this can be an alias ARN.

Copy link
Contributor

Choose a reason for hiding this comment

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

Or a link to the KMS examples?
We don't want any given example
to be so complete that it tries to explain everything.


## 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.
Copy link
Contributor

Choose a reason for hiding this comment

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

Some of this language is getting copy/paste.
Not a blocker, but in the long run, some more tokenization may be in order.

#
# 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())
```
114 changes: 114 additions & 0 deletions examples/templates/api/one-step-in-memory.md
Original file line number Diff line number Diff line change
@@ -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)](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

### 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())
```
138 changes: 138 additions & 0 deletions examples/templates/api/streaming-file-to-file.md
Original file line number Diff line number Diff line change
@@ -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)](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:
Copy link
Contributor

Choose a reason for hiding this comment

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

Yup, I think that this is so language specific,
that maybe nothing is better?
(in the long run :) no need to block )

# 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)
```
Loading