Encryption using Python and AWS

In this post I’ll show you how to encrypt and decrypt strings using the AWS Encryption SDK and AWS KMS.

Step 1: Install the AWS SDK for Python and the Encryption SDK

pip install boto3
pip install aws-encryption-sdk

You’ll need boto3 to create a Master Key programmatically and the aws-encryption-sdk for encrypting and decrypting data.

Step 2: Add AWS credentials to the environment

If you have the AWS CLI installed, run aws configure in the terminal. It will prompt you to enter your user’s access and secret keys. If you don’t have the CLI installed, add the credentials to the system variables manually by running the following commands:

$ export AWS_ACCESS_KEY_ID=<your access Key ID>
$ export AWS_SECRET_ACCESS_KEY=<your secret access Key>

The SDK’s will use these credentials to authenticate with AWS services in the next steps

Step 3: Create a Customer Master Key in AWS.

In the examples below, we’ll use the AWS Encryption SDK to implement envelope encryption. Envelope encryption is a type of encryption where you use a local data key to encrypt plaintext data and then encrypting the data key using a Customer Master Key. The Customer Master Key or CMK is stored in AWS and is never transferred unencrypted. A CMK can be created using the AWS console, the CLI or using an AWS SDK like boto3. To create a CMK using boto3:

import boto3

session = boto3.session.Session()
client = session.client("kms")

# create a new CMK
response = client.create_key(Description="My Key", CustomerMasterKeySpec="SYMMETRIC_DEFAULT", Origin="AWS_KMS",multi_region=False)

# The response contains information about your newly created key
metadata = response.get("KeyMetadata")
key_arn = metadata.get("Arn")


The code above shows how to create a symmetric encryption key that can only be used in a single AWS region. If you’d like to create asymmetric keys or want more advanced features, consult the AWS docs.

The advantage of using AWS for key management is that the keys never leave AWS unencrypted, key management is centralised and keys can be rotated easily. Now that you have created a CMK, you can use it for local cryptographic operations in your programs.

The example below uses the AWS Encryption SDK. The SDK protects sensitive data using best practices and industry standards. For example, it uses an algorithm suite with AES-GCM with an HMAC-based extract-and-expand key derivation function (HKDF), signing, and a 256-bit encryption key and envelope encryption without requiring any special expertise.

The code below shows how to encrypt and decrypt a string using the SDK:

# app.py

import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy

# Use the key arn you obtained in the previous step
key_arn = "arn:aws:kms:af-south-1:120000111111:key/a3d4f5bc-be67-82de-849b-123456c7890f"

client = aws_encryption_sdk.EncryptionSDKClient(
    commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)

# Create an AWS KMS master key provider
kms_kwargs = dict(key_ids=[key_arn])

master_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(**kms_kwargs)


def encrypt_string(plaintext):

    encrypted_text, encryptor_header = client.encrypt(
        source=plaintext, key_provider=master_key_provider
    )
    return encrypted_text


def decrypt_string(ciphertext):

    decrypted_text, encryptor_header = client.decrypt(
        source=ciphertext, key_provider=master_key_provider
    )
    return decrypted_text.decode()


if __name__ == "__main__":

    plaintext = "hello world"

    # Encrypt the plaintext source data
    encrypted_text = encrypt_string(plaintext)

    print(f"Encrypted text: {encrypted_text}")
    print()

    decrypted_text = decrypt_string(encrypted_text)
    print(f"Decrypted text: {decrypted_text}")

Run the code in the terminal:

$ python app.py

Encrypted text: b'\x02\x05xgM<\x8f5w\x97\xbb&Q\xe7\xabj\x13)K\x0c\xa6\xb2\x80\xe0\x1d\xbdol\xc6\\

Decrypted text: hello world

Conclusion

In this post you saw how to create a Master Key in AWS Key Management Service and use that key to encrypt and decrypt data using the AWS Encryption SDK. If you would like to know more, head to the AWS Docs.

Thank you for reading. If you liked this post, consider subscribing or following me on Twitter so you never miss a post.