Skip to content

feat: revert keyrings #271

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
43 changes: 0 additions & 43 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,6 @@
Changelog
*********

1.5.0 -- 2020-xx-xx
===================

Major Features
--------------

* Add `keyrings`_.
* Change one-step APIs to return a :class:`CryptoResult` rather than a tuple.

* Modified APIs: ``aws_encryption_sdk.encrypt`` and ``aws_encryption_sdk.decrypt``.

.. note::

For backwards compatibility,
:class:`CryptoResult` also unpacks like a 2-member tuple.
This allows for backwards compatibility with the previous outputs
so this change should not break any existing consumers
unless you are specifically relying on the output being an instance of :class:`tuple`.

Deprecations
------------

* Deprecate master key providers in favor of keyrings.

* We still support using master key providers and are not removing them yet.
When we decide to remove them,
we will communicate that as defined in our versioning policy.

* Deprecate support for Python 3.4.

* This does not mean that this library will no longer work or install with 3.4,
but we are no longer testing against or advertising support for 3.4.

Documentation
-------------

* Added new examples demonstrating how to use
APIs, keyrings, cryptographic materials managers, and master key providers.
`#221 <https://github.com/aws/aws-encryption-sdk-python/pull/221>`_
`#236 <https://github.com/aws/aws-encryption-sdk-python/pull/236>`_
`#239 <https://github.com/aws/aws-encryption-sdk-python/pull/239>`_

1.4.1 -- 2019-09-20
===================

Expand Down Expand Up @@ -235,4 +193,3 @@ Minor
.. _pylint: https://www.pylint.org/
.. _flake8: http://flake8.pycqa.org/en/latest/
.. _doc8: https://launchpad.net/doc8
.. _keyrings: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html
199 changes: 173 additions & 26 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Getting Started
Required Prerequisites
======================

* Python 2.7 or 3.5+
* Python 2.7+ or 3.4+
* cryptography >= 1.8.1
* boto3
* attrs
Expand All @@ -57,42 +57,189 @@ Installation

Concepts
========
There are three main concepts that are helpful to understand when using the AWS Encryption SDK.

For further information, see the `AWS Encryption SDK developer guide concepts`_.
There are four main concepts that you need to understand to use this library:

Cryptographic Materials Managers
--------------------------------
The cryptographic materials manager (CMM) assembles the cryptographic materials
that are used to encrypt and decrypt data.
Cryptographic materials managers (CMMs) are resources that collect cryptographic materials and prepare them for
use by the Encryption SDK core logic.

`For more details,
see the AWS Encryption SDK developer guide cryptographic materials manager concept.
<https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#crypt-materials-manager>`_
An example of a CMM is the default CMM, which is automatically generated anywhere a caller provides a master
key provider. The default CMM collects encrypted data keys from all master keys referenced by the master key
provider.

Keyrings
--------
An example of a more advanced CMM is the caching CMM, which caches cryptographic materials provided by another CMM.

A keyring generates, encrypts, and decrypts data keys.
Master Key Providers
--------------------
Master key providers are resources that provide master keys.
An example of a master key provider is `AWS KMS`_.

`For more details,
see the AWS Encryption SDK developer guide keyring concept.
<https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#keyring>`_
To encrypt data in this client, a ``MasterKeyProvider`` object must contain at least one ``MasterKey`` object.

Data Keys
---------
``MasterKeyProvider`` objects can also contain other ``MasterKeyProvider`` objects.

A data key is an encryption key that the AWS Encryption SDK uses to encrypt your data.
Master Keys
-----------
Master keys generate, encrypt, and decrypt data keys.
An example of a master key is a `KMS customer master key (CMK)`_.

`For more details,
see the AWS Encryption SDK developer guide data key concept.
<https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#DEK>`_
Data Keys
---------
Data keys are the encryption keys that are used to encrypt your data. If your algorithm suite
uses a key derivation function, the data key is used to generate the key that directly encrypts the data.

*****
Usage
*****
To use this client, you (the caller) must provide an instance of either a master key provider
or a CMM. The examples in this readme use the ``KMSMasterKeyProvider`` class.

KMSMasterKeyProvider
====================
Because the ``KMSMasterKeyProvider`` uses the `boto3 SDK`_ to interact with `AWS KMS`_, it requires AWS Credentials.
To provide these credentials, use the `standard means by which boto3 locates credentials`_ or provide a
pre-existing instance of a ``botocore session`` to the ``KMSMasterKeyProvider``.
This latter option can be useful if you have an alternate way to store your AWS credentials or
you want to reuse an existing instance of a botocore session in order to decrease startup costs.

.. code:: python

import aws_encryption_sdk
import botocore.session

kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider()

existing_botocore_session = botocore.session.Session()
kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(botocore_session=existing_botocore_session)


You can pre-load the ``KMSMasterKeyProvider`` with one or more CMKs.
To encrypt data, you must configure the ``KMSMasterKeyProvider`` with as least one CMK.
If you configure the the ``KMSMasterKeyProvider`` with multiple CMKs, the `final message`_
will include a copy of the data key encrypted by each configured CMK.

.. code:: python

import aws_encryption_sdk

kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[
'arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222',
'arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333'
])

You can add CMKs from multiple regions to the ``KMSMasterKeyProvider``.

.. code:: python

import aws_encryption_sdk

kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[
'arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222',
'arn:aws:kms:us-west-2:3333333333333:key/33333333-3333-3333-3333-333333333333',
'arn:aws:kms:ap-northeast-1:4444444444444:key/44444444-4444-4444-4444-444444444444'
])


Encryption and Decryption
=========================
After you create an instance of a ``MasterKeyProvider``, you can use either of the two
high-level ``encrypt``/``decrypt`` functions to encrypt and decrypt your data.

.. code:: python

import aws_encryption_sdk

kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[
'arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222',
'arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333'
])
my_plaintext = b'This is some super secret data! Yup, sure is!'

my_ciphertext, encryptor_header = aws_encryption_sdk.encrypt(
source=my_plaintext,
key_provider=kms_key_provider
)

decrypted_plaintext, decryptor_header = aws_encryption_sdk.decrypt(
source=my_ciphertext,
key_provider=kms_key_provider
)

assert my_plaintext == decrypted_plaintext
assert encryptor_header.encryption_context == decryptor_header.encryption_context

You can provide an `encryption context`_: a form of additional authenticating information.

.. code:: python

import aws_encryption_sdk

kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[
'arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222',
'arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333'
])
my_plaintext = b'This is some super secret data! Yup, sure is!'

my_ciphertext, encryptor_header = aws_encryption_sdk.encrypt(
source=my_plaintext,
key_provider=kms_key_provider,
encryption_context={
'not really': 'a secret',
'but adds': 'some authentication'
}
)

decrypted_plaintext, decryptor_header = aws_encryption_sdk.decrypt(
source=my_ciphertext,
key_provider=kms_key_provider
)

assert my_plaintext == decrypted_plaintext
assert encryptor_header.encryption_context == decryptor_header.encryption_context


Streaming
=========
If you are handling large files or simply do not want to put the entire plaintext or ciphertext in
memory at once, you can use this library's streaming clients directly. The streaming clients are
file-like objects, and behave exactly as you would expect a Python file object to behave,
offering context manager and iteration support.

.. code:: python

import aws_encryption_sdk
import filecmp

kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[
'arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222',
'arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333'
])
plaintext_filename = 'my-secret-data.dat'
ciphertext_filename = 'my-encrypted-data.ct'

with open(plaintext_filename, 'rb') as pt_file, open(ciphertext_filename, 'wb') as ct_file:
with aws_encryption_sdk.stream(
mode='e',
source=pt_file,
key_provider=kms_key_provider
) as encryptor:
for chunk in encryptor:
ct_file.write(chunk)

new_plaintext_filename = 'my-decrypted-data.dat'

For examples of how to use these concepts to accomplish different tasks, see our `examples`_.
with open(ciphertext_filename, 'rb') as ct_file, open(new_plaintext_filename, 'wb') as pt_file:
with aws_encryption_sdk.stream(
mode='d',
source=ct_file,
key_provider=kms_key_provider
) as decryptor:
for chunk in decryptor:
pt_file.write(chunk)

assert filecmp.cmp(plaintext_filename, new_plaintext_filename)
assert encryptor.header.encryption_context == decryptor.header.encryption_context

Performance Considerations
==========================
Expand All @@ -104,14 +251,14 @@ to your use-case in order to obtain peak performance.


.. _AWS Encryption SDK: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html
.. _AWS Encryption SDK developer guide concepts:
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html
.. _cryptography: https://cryptography.io/en/latest/
.. _cryptography installation guide: https://cryptography.io/en/latest/installation/
.. _Read the Docs: http://aws-encryption-sdk-python.readthedocs.io/en/latest/
.. _GitHub: https://github.com/aws/aws-encryption-sdk-python/
.. _AWS KMS: https://docs.aws.amazon.com/kms/latest/developerguide/overview.html
.. _KMS customer master key (CMK): https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys
.. _boto3 SDK: https://boto3.readthedocs.io/en/latest/
.. _standard means by which boto3 locates credentials: https://boto3.readthedocs.io/en/latest/guide/configuration.html
.. _final message: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/message-format.html
.. _encryption context: https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context
.. _examples: https://github.com/aws/aws-encryption-sdk-python/tree/master/examples
.. _Security issue notifications: https://github.com/aws/aws-encryption-sdk-python/tree/master/CONTRIBUTING.md#security-issue-notifications
.. _Security issue notifications: ./CONTRIBUTING.md#security-issue-notifications
Loading