Package: aws-encryption-sdk
The AWS Encryption SDK for Python provides a fully compliant, native Python implementation of theAWS Encryption SDK.The latest full documentation can be found atRead the Docs.Find us onGitHub.Security issue notificationsSeeSupport Policyfor details on the current support status of all major versions of this library.Getting StartedRequired PrerequisitesPython 3.6+cryptography >= 2.5.0boto3 >= 1.10.0attrsInstallationNoteIf you have not already installedcryptography, you might need to install additional prerequisites as
detailed in thecryptography installation guidefor your operating system.$ pip install aws-encryption-sdkConceptsThere are four main concepts that you need to understand to use this library:Cryptographic Materials ManagersCryptographic materials managers (CMMs) are resources that collect cryptographic materials and prepare them for
use by the Encryption SDK core logic.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.An example of a more advanced CMM is the caching CMM, which caches cryptographic materials provided by another CMM.Master Key ProvidersMaster key providers are resources that provide master keys.
An example of a master key provider isAWS KMS.To encrypt data in this client, aMasterKeyProviderobject must contain at least oneMasterKeyobject.MasterKeyProviderobjects can also contain otherMasterKeyProviderobjects.Master KeysMaster keys generate, encrypt, and decrypt data keys.
An example of a master key is aKMS customer master key (CMK).Data KeysData 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.UsageEncryptionSDKClientTo use this module, you (the caller) must first create an instance of theEncryptionSDKClientclass.
The constructor to this class accepts an optional keyword argument,commitment_policy, that controls
which algorithm suites can be used for encryption and decryption. If no value
is provided for this argument, a default value ofREQUIRE_ENCRYPT_REQUIRE_DECRYPTis used. Unless
you have specialized performance requirements or are in the process of migrating from an older
version of the AWS Encryption SDK, we recommend using the default value.importaws_encryption_sdkfromaws_encryption_sdk.identifiersimportCommitmentPolicyclient=aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT)You must then create an instance of either a master key provider or a CMM. The examples in this
readme use theStrictAwsKmsMasterKeyProviderclass.StrictAwsKmsMasterKeyProviderAStrictAwsKmsMasterKeyProvideris configured with an explicit list of AWS KMS
CMKs with which to encrypt and decrypt data. On encryption, it encrypts the plaintext with all
configured CMKs. On decryption, it only attempts to decrypt ciphertexts that have been wrapped
with a CMK that matches one of the configured CMK ARNs.To create aStrictAwsKmsMasterKeyProvideryou must provide one or more CMKs. For providers that will only
be used for encryption, you can use any validKMS key identifier. For providers that will be used for decryption, you
must use the key ARN; key ids, alias names, and alias ARNs are not supported.Because theStrictAwsKmsMasterKeyProvideruses theboto3 SDKto interact withAWS KMS,
it requires AWS Credentials.
To provide these credentials, use thestandard means by which boto3 locates credentialsor provide a
pre-existing instance of abotocore sessionto theStrictAwsKmsMasterKeyProvider.
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.If you configure the theStrictAwsKmsMasterKeyProviderwith multiple CMKs, thefinal messagewill include a copy of the data key encrypted by each configured CMK.importaws_encryption_sdkkms_key_provider=aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(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 theStrictAwsKmsMasterKeyProvider.importaws_encryption_sdkkms_key_provider=aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(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'])DiscoveryAwsKmsMasterKeyProviderWe recommend using aStrictAwsKmsMasterKeyProviderin order to ensure that you can only
encrypt and decrypt data using the AWS KMS CMKs you expect. However, if you are unable to
explicitly identify the AWS KMS CMKs that should be used for decryption, you can instead
use aDiscoveryAwsKmsMasterKeyProviderfor decryption operations. This provider
attempts decryption of any ciphertexts as long as they match aDiscoveryFilterthat
you configure. ADiscoveryFilterconsists of a list of AWS account ids and an AWS
partition.importaws_encryption_sdkfromaws_encryption_sdk.key_providers.kmsimportDiscoveryFilterdiscovery_filter=DiscoveryFilter(account_ids=['222222222222','333333333333'],partition='aws')kms_key_provider=aws_encryption_sdk.DiscoveryAwsKmsMasterKeyProvider(discovery_filter=discovery_filter)If you do not want to filter the set of allowed accounts, you can also omit thediscovery_filterargument.Note that aDiscoveryAwsKmsMasterKeyProvidercannot be used for encryption operations.Encryption and DecryptionAfter you create an instance of anEncryptionSDKClientand aMasterKeyProvider, you can use either of
the client’s twoencrypt/decryptfunctions to encrypt and decrypt your data.importaws_encryption_sdkfromaws_encryption_sdk.identifiersimportCommitmentPolicyclient=aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT)kms_key_provider=aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(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=client.encrypt(source=my_plaintext,key_provider=kms_key_provider)decrypted_plaintext,decryptor_header=client.decrypt(source=my_ciphertext,key_provider=kms_key_provider)assertmy_plaintext==decrypted_plaintextassertencryptor_header.encryption_context==decryptor_header.encryption_contextYou can provide anencryption context: a form of additional authenticating information.importaws_encryption_sdkfromaws_encryption_sdk.identifiersimportCommitmentPolicyclient=aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT)kms_key_provider=aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(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=client.encrypt(source=my_plaintext,key_provider=kms_key_provider,encryption_context={'not really':'a secret','but adds':'some authentication'})decrypted_plaintext,decryptor_header=client.decrypt(source=my_ciphertext,key_provider=kms_key_provider)assertmy_plaintext==decrypted_plaintextassertencryptor_header.encryption_context==decryptor_header.encryption_contextStreamingIf 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.importaws_encryption_sdkfromaws_encryption_sdk.identifiersimportCommitmentPolicyimportfilecmpclient=aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT)kms_key_provider=aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(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'withopen(plaintext_filename,'rb')aspt_file,open(ciphertext_filename,'wb')asct_file:withclient.stream(mode='e',source=pt_file,key_provider=kms_key_provider)asencryptor:forchunkinencryptor:ct_file.write(chunk)new_plaintext_filename='my-decrypted-data.dat'withopen(ciphertext_filename,'rb')asct_file,open(new_plaintext_filename,'wb')aspt_file:withclient.stream(mode='d',source=ct_file,key_provider=kms_key_provider)asdecryptor:forchunkindecryptor:pt_file.write(chunk)assertfilecmp.cmp(plaintext_filename,new_plaintext_filename)assertencryptor.header.encryption_context==decryptor.header.encryption_contextPerformance ConsiderationsAdjusting the frame size can significantly improve the performance of encrypt/decrypt operations with this library.Processing each frame in a framed message involves a certain amount of overhead.  If you are encrypting a large file,
increasing the frame size can offer potentially significant performance gains.  We recommend that you tune these values
to your use-case in order to obtain peak performance.