Skip to content

chore: added examples for raw rsa and raw aes keyrings #661

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 189 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
189 commits
Select commit Hold shift + click to select a range
7360edd
passing hierarchy keyring example
lucasmcdonald3 Jan 31, 2024
53c46ec
cleanup
lucasmcdonald3 Feb 2, 2024
3f5a503
add
lucasmcdonald3 Feb 2, 2024
16cf5c1
changes, cleanup:
lucasmcdonald3 Feb 2, 2024
5b5aa07
changes, cleanup
lucasmcdonald3 Feb 2, 2024
03e19ca
flake8
lucasmcdonald3 Feb 2, 2024
b5d3327
flake8
lucasmcdonald3 Feb 2, 2024
b13cd19
flake8
lucasmcdonald3 Feb 2, 2024
51065cb
flake8
lucasmcdonald3 Feb 2, 2024
fc4d254
flake8
lucasmcdonald3 Feb 2, 2024
a8e52d3
fix pem/der
lucasmcdonald3 Feb 5, 2024
6f55047
fix pem/der
lucasmcdonald3 Feb 5, 2024
1b1b4e4
debug
lucasmcdonald3 Feb 6, 2024
38a4cc9
debug
lucasmcdonald3 Feb 6, 2024
0cd0e23
fix
lucasmcdonald3 Feb 6, 2024
44826a2
fix
lucasmcdonald3 Feb 7, 2024
02e9f84
fix
lucasmcdonald3 Feb 7, 2024
a3babfd
linter
lucasmcdonald3 Feb 7, 2024
d2c974a
linter
lucasmcdonald3 Feb 7, 2024
55b24a8
isort
lucasmcdonald3 Feb 7, 2024
7e5fa48
flake8 examples
lucasmcdonald3 Feb 7, 2024
055deab
isort + flake8
lucasmcdonald3 Feb 7, 2024
6cf01d4
flake8/pylint examples
lucasmcdonald3 Feb 7, 2024
00cfed1
reset tests
lucasmcdonald3 Feb 7, 2024
61bbb3b
extend mpl
lucasmcdonald3 Feb 7, 2024
4d53ad6
mpl gha
lucasmcdonald3 Feb 7, 2024
c1736d3
debug
lucasmcdonald3 Feb 7, 2024
9991789
debug
lucasmcdonald3 Feb 7, 2024
a501e8f
debug
lucasmcdonald3 Feb 7, 2024
6eb8f82
debug
lucasmcdonald3 Feb 7, 2024
5ccfa0c
codebuild mpl
lucasmcdonald3 Feb 7, 2024
5e7ec9b
codebuild mpl
lucasmcdonald3 Feb 7, 2024
cc48697
codebuild mpl
lucasmcdonald3 Feb 7, 2024
fae43d1
codebuild mpl
lucasmcdonald3 Feb 7, 2024
2637616
debug
lucasmcdonald3 Feb 7, 2024
2694932
debug
lucasmcdonald3 Feb 7, 2024
f674d3e
debug
lucasmcdonald3 Feb 7, 2024
0b5e655
debug
lucasmcdonald3 Feb 7, 2024
831df17
debug
lucasmcdonald3 Feb 7, 2024
477e3a0
debug
lucasmcdonald3 Feb 7, 2024
166c5ab
debug
lucasmcdonald3 Feb 7, 2024
7ac8880
debug
lucasmcdonald3 Feb 7, 2024
8193c25
Merge branch 'master' into lucmcdon/mpl
lucasmcdonald3 Feb 7, 2024
7e3ca15
fix
lucasmcdonald3 Feb 7, 2024
4c6a1d0
fix
lucasmcdonald3 Feb 7, 2024
e2e1858
fix
lucasmcdonald3 Feb 7, 2024
c790011
mpl
lucasmcdonald3 Feb 7, 2024
33ace58
fix
lucasmcdonald3 Feb 7, 2024
cbf2cdf
fix
lucasmcdonald3 Feb 7, 2024
b259477
fix
lucasmcdonald3 Feb 7, 2024
9d52cf2
.
lucasmcdonald3 Feb 8, 2024
31b7616
debug tox mpl keystore env
lucasmcdonald3 Feb 9, 2024
353b8cf
debug tox mpl keystore env
lucasmcdonald3 Feb 9, 2024
fb64d95
debug tox mpl keystore env
lucasmcdonald3 Feb 9, 2024
916ae8e
debug tox mpl keystore env
lucasmcdonald3 Feb 9, 2024
222b135
debug tox mpl keystore env
lucasmcdonald3 Feb 9, 2024
cab6016
some unit tests
lucasmcdonald3 Feb 10, 2024
a7416b1
add mpl coverage
lucasmcdonald3 Feb 13, 2024
7b3dc5f
.
lucasmcdonald3 Feb 13, 2024
7a5e4eb
.
lucasmcdonald3 Feb 13, 2024
0649995
mock imports
lucasmcdonald3 Feb 13, 2024
6691fa2
refactor, fix
lucasmcdonald3 Feb 20, 2024
3ae1e06
refactor, fix
lucasmcdonald3 Feb 20, 2024
2b5fc72
refactor, fix
lucasmcdonald3 Feb 20, 2024
a940dc5
refactor, fix
lucasmcdonald3 Feb 20, 2024
708ab5e
it works locally but fails on gha
lucasmcdonald3 Feb 20, 2024
ffd295c
it works locally but fails on gha
lucasmcdonald3 Feb 20, 2024
1ba175c
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
fa175ba
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
2f90a97
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
df9215f
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
b57e4a3
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
9d7ec6d
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
2cbc845
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
def946d
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
dff6ac0
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
78f0b0f
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
20a469e
it works locally but fails on gha
lucasmcdonald3 Feb 21, 2024
66859a7
fix tests
lucasmcdonald3 Feb 21, 2024
bf8f67c
cleanup
lucasmcdonald3 Feb 21, 2024
b24be11
re-enable test
lucasmcdonald3 Feb 21, 2024
acba1b0
re-enable test
lucasmcdonald3 Feb 21, 2024
42b7b74
longpaths
lucasmcdonald3 Feb 21, 2024
f226e7e
longpaths
lucasmcdonald3 Feb 21, 2024
aa2f80a
debug windows fail
lucasmcdonald3 Feb 21, 2024
bc002b6
debug windows fail
lucasmcdonald3 Feb 21, 2024
8dd0303
debug windows fail
lucasmcdonald3 Feb 21, 2024
1e9db3b
debug windows fail
lucasmcdonald3 Feb 21, 2024
74d4e66
disable windows until pythonpath
lucasmcdonald3 Feb 21, 2024
1bb23e8
expand testing
lucasmcdonald3 Feb 21, 2024
1ee69ce
expand testing
lucasmcdonald3 Feb 21, 2024
b33f2f7
expand testing
lucasmcdonald3 Feb 21, 2024
c582888
expand testing
lucasmcdonald3 Feb 21, 2024
5ae44f5
expand testing
lucasmcdonald3 Feb 21, 2024
cb7e3d1
cleanup
lucasmcdonald3 Feb 21, 2024
b026b53
cleanup
lucasmcdonald3 Feb 21, 2024
50afa3a
cleanup
lucasmcdonald3 Feb 21, 2024
1c612a0
cleanup
lucasmcdonald3 Feb 21, 2024
bcdb4ba
add missing file
lucasmcdonald3 Feb 21, 2024
41fe2f9
add missing file
lucasmcdonald3 Feb 21, 2024
1ba857e
add missing file
lucasmcdonald3 Feb 21, 2024
74bfe12
cleanup
lucasmcdonald3 Feb 21, 2024
b3b9a0f
refactor
lucasmcdonald3 Feb 22, 2024
a594125
refactor
lucasmcdonald3 Feb 22, 2024
fdd2eda
unit tests
lucasmcdonald3 Feb 23, 2024
0138f22
unit tests
lucasmcdonald3 Feb 23, 2024
f213e19
upgrade image
lucasmcdonald3 Feb 23, 2024
d55f296
refactor tests
lucasmcdonald3 Feb 23, 2024
5ec4668
refactor tests
lucasmcdonald3 Feb 23, 2024
61ba4de
refactor tests
lucasmcdonald3 Feb 23, 2024
95c5be6
refactor tests
lucasmcdonald3 Feb 23, 2024
9566873
refactor tests
lucasmcdonald3 Feb 23, 2024
6642083
fix cov
lucasmcdonald3 Feb 23, 2024
51d2804
fix cov
lucasmcdonald3 Feb 23, 2024
51e5db5
fix cov
lucasmcdonald3 Feb 23, 2024
e235461
fix cov
lucasmcdonald3 Feb 23, 2024
e7c745f
fix tests
lucasmcdonald3 Feb 23, 2024
fee4f36
test cleanup
lucasmcdonald3 Feb 24, 2024
ac6471a
test cleanup
lucasmcdonald3 Feb 24, 2024
a5ebc19
isort
lucasmcdonald3 Feb 24, 2024
21f3614
fixes
lucasmcdonald3 Feb 24, 2024
22eabb6
fix
lucasmcdonald3 Feb 24, 2024
ac0ceb3
fix
lucasmcdonald3 Feb 24, 2024
2fd8858
oops
lucasmcdonald3 Feb 24, 2024
51c6a9c
revert
lucasmcdonald3 Feb 24, 2024
800f9de
revert
lucasmcdonald3 Feb 24, 2024
ebcb759
fix
lucasmcdonald3 Feb 24, 2024
cf26ca3
fix
lucasmcdonald3 Feb 24, 2024
7f27ebd
fix
lucasmcdonald3 Feb 24, 2024
00f4721
fix
lucasmcdonald3 Feb 24, 2024
018b93f
fix
lucasmcdonald3 Feb 24, 2024
d413b65
fix
lucasmcdonald3 Feb 24, 2024
c4ca658
copyright
lucasmcdonald3 Feb 24, 2024
d99b666
more unit tests
lucasmcdonald3 Feb 26, 2024
49cb7c8
more unit tests
lucasmcdonald3 Feb 26, 2024
705113a
more unit tests
lucasmcdonald3 Feb 26, 2024
f76d7f9
more unit tests
lucasmcdonald3 Feb 26, 2024
0da2a4f
more unit tests
lucasmcdonald3 Feb 26, 2024
0040b2c
cleanup
lucasmcdonald3 Feb 26, 2024
9131433
cleanup
lucasmcdonald3 Feb 26, 2024
e6826eb
poc impl
lucasmcdonald3 Feb 28, 2024
a9fa1a5
passing
lucasmcdonald3 Feb 28, 2024
4eeb858
cleanup
lucasmcdonald3 Feb 28, 2024
21a8c93
protect
lucasmcdonald3 Feb 29, 2024
de870b8
ex
lucasmcdonald3 Feb 29, 2024
eedf1a3
changes
lucasmcdonald3 Feb 29, 2024
1db73eb
changes
lucasmcdonald3 Feb 29, 2024
8415c2c
cleanup
lucasmcdonald3 Feb 29, 2024
20bdaff
cleanup
lucasmcdonald3 Feb 29, 2024
6bf6094
cleanup
lucasmcdonald3 Feb 29, 2024
febe6db
cleanup
lucasmcdonald3 Feb 29, 2024
dc8abca
cleanup
lucasmcdonald3 Feb 29, 2024
8ff46f4
cleanup
lucasmcdonald3 Feb 29, 2024
aba7ccc
cleanup
lucasmcdonald3 Feb 29, 2024
40fecc0
all message format versions
lucasmcdonald3 Feb 29, 2024
52043b9
sync upstream
lucasmcdonald3 Feb 29, 2024
14c287d
Merge
lucasmcdonald3 Mar 13, 2024
2d26009
Merge branch 'lucmcdon/mpl' into lucmcdon/mpl-requiredec
lucasmcdonald3 Mar 13, 2024
7374fcb
unit tests
lucasmcdonald3 Mar 26, 2024
f9d60a8
lint
lucasmcdonald3 Mar 26, 2024
16725f8
lint
lucasmcdonald3 Mar 26, 2024
1706db2
lint
lucasmcdonald3 Mar 26, 2024
06e0842
lint
lucasmcdonald3 Mar 26, 2024
5ad8e3a
Update examples/src/keyrings/hierarchical_keyring.py
lucasmcdonald3 Apr 15, 2024
280e038
Update examples/src/keyrings/hierarchical_keyring.py
lucasmcdonald3 Apr 16, 2024
0dfeb5d
Adding test for KMS keyring
RitvikKapila Apr 18, 2024
18328ad
chore: KMS keyring example
RitvikKapila Apr 19, 2024
a7feaaf
chore: verified flake8 and isort checks for aws_kms_keyring_example.py
RitvikKapila Apr 19, 2024
cad5a88
chore: valid isort and flake8 for all files
RitvikKapila Apr 19, 2024
1c43dd9
chore: minor comment fixes
RitvikKapila Apr 19, 2024
6f16233
chore: added examples for raw rsa and raw aes keyrings
RitvikKapila Apr 23, 2024
8222cea
removed kms keyring from this PR
RitvikKapila Apr 23, 2024
6b88b54
updated test_i_raw_rsa_keyring_example.py
RitvikKapila Apr 23, 2024
37ce803
updated ../../src/keyrings/raw_rsa_keyring_example.py
RitvikKapila Apr 23, 2024
2e19e1a
reverted test_i_hierarchical_keyring to previous version
RitvikKapila Apr 23, 2024
8039f62
reverted test_i_hierarchical_keyring to previous version
RitvikKapila Apr 24, 2024
7799a57
chore: updated raw rsa and aes keyrings
RitvikKapila Apr 25, 2024
3c5c5a0
chore: minor fix
RitvikKapila Apr 25, 2024
59faa8c
fix: raise assertion error instead of assert False
RitvikKapila Apr 25, 2024
5d698db
chore: updated and refactored raw rsa keyring example
RitvikKapila Apr 25, 2024
f6e53e2
minor fix
RitvikKapila Apr 25, 2024
ac96226
minor fix
RitvikKapila Apr 25, 2024
1814922
Merge branch 'mpl-reviewed' into rkapila/mpl-requiredec-raw
RitvikKapila Apr 26, 2024
877a7b9
Update test_streaming_client_stream_decryptor.py
RitvikKapila Apr 26, 2024
a60d67e
Merge branch 'mpl-reviewed' into rkapila/mpl-requiredec-raw
RitvikKapila May 1, 2024
69abc8b
updated raw rsa keyring to get keys from user files
RitvikKapila May 2, 2024
72c1c31
reset
lucasmcdonald3 May 2, 2024
e6bc447
fix
RitvikKapila May 2, 2024
2d7c5a9
fix
RitvikKapila May 2, 2024
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ __pycache__

# PyTest
.pytest_cache
# Ignore key materials generated by examples or tests
test_keys/

# PyCharm
.idea/
Expand Down
129 changes: 129 additions & 0 deletions examples/src/keyrings/raw_aes_keyring_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
This example sets up the Raw AES Keyring

The Raw AES keyring lets you use an AES symmetric key that you provide as a wrapping key that
protects your data key. You need to generate, store, and protect the key material,
preferably in a hardware security module (HSM) or key management system. Use a Raw AES keyring
when you need to provide the wrapping key and encrypt the data keys locally or offline.

This example creates a Raw AES Keyring and then encrypts a custom input EXAMPLE_DATA
with an encryption context. This example also includes some sanity checks for demonstration:
1. Ciphertext and plaintext data are not the same
2. Encryption context is correct in the decrypted message header
3. Decrypted plaintext value matches EXAMPLE_DATA
These sanity checks are for demonstration in the example only. You do not need these in your code.

The Raw AES keyring encrypts data by using the AES-GCM algorithm and a wrapping key that
you specify as a byte array. You can specify only one wrapping key in each Raw AES keyring,
but you can include multiple Raw AES keyrings, alone or with other keyrings, in a multi-keyring.

For more information on how to use Raw AES keyrings, see
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-raw-aes-keyring.html
"""
import secrets
import sys

from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
from aws_cryptographic_materialproviders.mpl.models import AesWrappingAlg, CreateRawAesKeyringInput
from aws_cryptographic_materialproviders.mpl.references import IKeyring
from typing import Dict

import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy

# TODO-MPL: Remove this as part of removing PYTHONPATH hacks.
MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1])

sys.path.append(MODULE_ROOT_DIR)

EXAMPLE_DATA: bytes = b"Hello World"


def encrypt_and_decrypt_with_keyring():
"""Demonstrate an encrypt/decrypt cycle using a Raw AES keyring.

Usage: encrypt_and_decrypt_with_keyring()
"""
# 1. Instantiate the encryption SDK client.
# This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy,
# which enforces that this client only encrypts using committing algorithm suites and enforces
# that this client will only decrypt encrypted messages that were created with a committing
# algorithm suite.
# This is the default commitment policy if you were to build the client as
# `client = aws_encryption_sdk.EncryptionSDKClient()`.
client = aws_encryption_sdk.EncryptionSDKClient(
commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)

# 2. The key namespace and key name are defined by you.
# and are used by the Raw AES keyring to determine
# whether it should attempt to decrypt an encrypted data key.
# For more information, see
# https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-raw-aes-keyring.html
key_name_space = "Some managed raw keys"
key_name = "My 256-bit AES wrapping key"

# 3. Create encryption context.
# Remember that your encryption context is NOT SECRET.
# For more information, see
# https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
encryption_context: Dict[str, str] = {
"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",
}

# 4. Generate a 256-bit AES key to use with your keyring.
# In practice, you should get this key from a secure key management system such as an HSM.

# Here, the input to secrets.token_bytes() = 32 bytes = 256 bits
static_key = secrets.token_bytes(32)

# 5. Create a Raw AES keyring
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
config=MaterialProvidersConfig()
)

keyring_input: CreateRawAesKeyringInput = CreateRawAesKeyringInput(
key_namespace=key_name_space,
key_name=key_name,
wrapping_key=static_key,
wrapping_alg=AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16
)

raw_aes_keyring: IKeyring = mat_prov.create_raw_aes_keyring(
input=keyring_input
)

# 6. Encrypt the data with the encryptionContext
ciphertext, _ = client.encrypt(
source=EXAMPLE_DATA,
keyring=raw_aes_keyring,
encryption_context=encryption_context
)

# 7. Demonstrate that the ciphertext and plaintext are different.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert ciphertext != EXAMPLE_DATA, \
"Ciphertext and plaintext data are the same. Invalid encryption"

# 8. Decrypt your encrypted data using the same keyring you used on encrypt.
plaintext_bytes, dec_header = client.decrypt(
source=ciphertext,
keyring=raw_aes_keyring
)

# 9. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA
249 changes: 249 additions & 0 deletions examples/src/keyrings/raw_rsa_keyring_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
This example sets up the Raw RSA Keyring

The Raw RSA keyring performs asymmetric encryption and decryption of data keys in local memory
with RSA public and private keys that you provide. In this example, we define the RSA keys to
encrypt and decrypt the data keys.

You need to generate, store, and protect the private key, preferably in a
hardware security module (HSM) or key management system.
The encryption function encrypts the data key under the RSA public key. The decryption function
decrypts the data key using the private key.

This example creates a Raw RSA Keyring and then encrypts a custom input EXAMPLE_DATA
with an encryption context. This example also includes some sanity checks for demonstration:
1. Ciphertext and plaintext data are not the same
2. Encryption context is correct in the decrypted message header
3. Decrypted plaintext value matches EXAMPLE_DATA
4. The original ciphertext is not decryptable using a keyring with a different RSA key pair
These sanity checks are for demonstration in the example only. You do not need these in your code.

A Raw RSA keyring that encrypts and decrypts must include an asymmetric public key and private
key pair. However, you can encrypt data with a Raw RSA keyring that has only a public key,
and you can decrypt data with a Raw RSA keyring that has only a private key. This example requires
the user to either provide both private and public keys, or not provide any keys and the example
generates both to test encryption and decryption. If you configure a Raw RSA keyring with a
public and private key, be sure that they are part of the same key pair. Some language
implementations of the AWS Encryption SDK will not construct a Raw RSA keyring with keys
from different pairs. Others rely on you to verify that your keys are from the same key pair.
You can include any Raw RSA keyring in a multi-keyring.

For more information on how to use Raw RSA keyrings, see
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-raw-rsa-keyring.html
"""
import sys

from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
from aws_cryptographic_materialproviders.mpl.models import CreateRawRsaKeyringInput, PaddingScheme
from aws_cryptographic_materialproviders.mpl.references import IKeyring
from cryptography.hazmat.backends import default_backend as crypto_default_backend
from cryptography.hazmat.primitives import serialization as crypto_serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from typing import Dict

import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy
from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError

# TODO-MPL: Remove this as part of removing PYTHONPATH hacks.
MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1])

sys.path.append(MODULE_ROOT_DIR)

EXAMPLE_DATA: bytes = b"Hello World"


def should_generate_new_rsa_key_pair(public_key_file_name, private_key_file_name):
"""Returns True if user doesn't provide keys, and we need to generate them;
Returns False if the user has already provided both public and private keys
Raises a ValueError if the user only provides one of private_key and public_key

Usage: should_generate_new_rsa_key_pair(public_key_file_name, private_key_file_name)
"""
# If only one of public_key and private_key files is provided, raise a ValueError
if (public_key_file_name and not private_key_file_name)\
or (not public_key_file_name and private_key_file_name):
raise ValueError("Either both public and private keys should be provided! Or no keys \
should be provided and the example can create the keys for you!")

# If no keys are provided, we should generate a new rsa key pair, so return True
if not public_key_file_name and not private_key_file_name:
return True

# If both keys are already provided, return False
return False


def generate_rsa_keys():
"""Generates a 4096-bit RSA public and private key pair

Usage: generate_rsa_keys()
"""
ssh_rsa_exponent = 65537
bit_strength = 4096
key = rsa.generate_private_key(
backend=crypto_default_backend(),
public_exponent=ssh_rsa_exponent,
key_size=bit_strength
)

# This example choses a particular type of encoding, format and encryption_algorithm
# Users can choose the PublicFormat, PrivateFormat and encryption_algorithm that align most
# with their use-cases
public_key = key.public_key().public_bytes(
encoding=crypto_serialization.Encoding.PEM,
format=crypto_serialization.PublicFormat.SubjectPublicKeyInfo
)
private_key = key.private_bytes(
encoding=crypto_serialization.Encoding.PEM,
format=crypto_serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=crypto_serialization.NoEncryption()
)

return public_key, private_key


def create_rsa_keyring(public_key, private_key):
"""Create a Raw RSA keyring using the key pair

Usage: create_rsa_keyring(public_key, private_key)
"""
# 1. The key namespace and key name are defined by you.
# and are used by the Raw RSA keyring
# For more information, see
# https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-raw-rsa-keyring.html
key_name_space = "Some managed raw keys"
key_name = "My 4096-bit RSA wrapping key"

# 2. Create a Raw RSA keyring
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
config=MaterialProvidersConfig()
)

keyring_input: CreateRawRsaKeyringInput = CreateRawRsaKeyringInput(
key_namespace=key_name_space,
key_name=key_name,
padding_scheme=PaddingScheme.OAEP_SHA256_MGF1,
public_key=public_key,
private_key=private_key
)

raw_rsa_keyring: IKeyring = mat_prov.create_raw_rsa_keyring(
input=keyring_input
)

return raw_rsa_keyring


def encrypt_and_decrypt_with_keyring(public_key_file_name=None, private_key_file_name=None):
"""Demonstrate an encrypt/decrypt cycle using a Raw RSA keyring
with user defined keys. If no keys are present, generate new RSA
public and private keys and use them to create a Raw RSA keyring

Usage: encrypt_and_decrypt_with_keyring(public_key_file_name, private_key_file_name)
"""
# 1. Instantiate the encryption SDK client.
# This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy,
# which enforces that this client only encrypts using committing algorithm suites and enforces
# that this client will only decrypt encrypted messages that were created with a committing
# algorithm suite.
# This is the default commitment policy if you were to build the client as
# `client = aws_encryption_sdk.EncryptionSDKClient()`.
client = aws_encryption_sdk.EncryptionSDKClient(
commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)

# 2. Create encryption context.
# Remember that your encryption context is NOT SECRET.
# For more information, see
# https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
encryption_context: Dict[str, str] = {
"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",
}

# 3. Create a Raw RSA keyring.
# If you have provided keys in a PEM file, they will be loaded into the keyring.
# Otherwise, a key pair will be randomly generated for you.

# Check if we need to generate an RSA key pair
should_generate_new_rsa_key_pair_bool = \
should_generate_new_rsa_key_pair(public_key_file_name=public_key_file_name,
private_key_file_name=private_key_file_name)

# If user doesn't provide the keys, that is, if should_generate_new_rsa_key_pair_bool is True
# generate a new RSA public and private key pair
if should_generate_new_rsa_key_pair_bool:
public_key, private_key = generate_rsa_keys()
else:
# If user provides the keys, read the keys from the files
with open(public_key_file_name, "r", encoding='utf-8') as f:
public_key = f.read()

# Convert the public key from a string to bytes
public_key = bytes(public_key, 'utf-8')

with open(private_key_file_name, "r", encoding='utf-8') as f:
private_key = f.read()

# Convert the private key from a string to bytes
private_key = bytes(private_key, 'utf-8')

# Create the keyring
raw_rsa_keyring = create_rsa_keyring(public_key=public_key, private_key=private_key)

# 4. Encrypt the data with the encryptionContext
ciphertext, _ = client.encrypt(
source=EXAMPLE_DATA,
keyring=raw_rsa_keyring,
encryption_context=encryption_context
)

# 5. Demonstrate that the ciphertext and plaintext are different.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert ciphertext != EXAMPLE_DATA, \
"Ciphertext and plaintext data are the same. Invalid encryption"

# 6. Decrypt your encrypted data using the same keyring you used on encrypt.
plaintext_bytes, dec_header = client.decrypt(
source=ciphertext,
keyring=raw_rsa_keyring
)

# 7. Demonstrate that the encryption context is correct in the decrypted message header
# (This is an example for demonstration; you do not need to do this in your own code.)
for k, v in encryption_context.items():
assert v == dec_header.encryption_context[k], \
"Encryption context does not match expected values"

# 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
# (This is an example for demonstration; you do not need to do this in your own code.)
assert plaintext_bytes == EXAMPLE_DATA

# The next part of the example creates a new RSA keyring (for Bob) to demonstrate that
# decryption of the original ciphertext is not possible with a different keyring (Bob's).
# (This is an example for demonstration; you do not need to do this in your own code.)

# 9. Create a new Raw RSA keyring for Bob
# Generate new keys
public_key_bob, private_key_bob = generate_rsa_keys()

# Create the keyring
raw_rsa_keyring_bob = create_rsa_keyring(public_key=public_key_bob, private_key=private_key_bob)

# 10. Test decrypt for the original ciphertext using raw_rsa_keyring_bob
try:
plaintext_bytes_bob, _ = client.decrypt(
source=ciphertext,
keyring=raw_rsa_keyring_bob
)

raise AssertionError("client.decrypt should throw an error of type AWSEncryptionSDKClientError!")
except AWSEncryptionSDKClientError:
pass
Loading
Loading