def test_raw_aes_encryption_decryption(encryption_materials_samples): # Initializing attributes key_namespace = _PROVIDER_ID key_name = _KEY_ID # Creating an instance of a raw AES keyring test_raw_aes_keyring = RawAESKeyring( key_namespace=key_namespace, key_name=key_name, wrapping_key=_WRAPPING_KEY, ) # Call on_encrypt function for the keyring encryption_materials = test_raw_aes_keyring.on_encrypt( encryption_materials=encryption_materials_samples) # Generate decryption materials decryption_materials = DecryptionMaterials( algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, verification_key=b"ex_verification_key", encryption_context=_ENCRYPTION_CONTEXT, ) # Call on_decrypt function for the keyring decryption_materials = test_raw_aes_keyring.on_decrypt( decryption_materials=decryption_materials, encrypted_data_keys=encryption_materials.encrypted_data_keys) # Check if the data keys match assert encryption_materials.data_encryption_key.data_key == decryption_materials.data_encryption_key.data_key
def test_raw_master_key_decrypts_what_raw_keyring_encrypts( encryption_materials_samples): # Initializing attributes key_namespace = _PROVIDER_ID key_name = _KEY_ID # Creating an instance of a raw AES keyring test_raw_aes_keyring = RawAESKeyring( key_namespace=key_namespace, key_name=key_name, wrapping_key=_WRAPPING_KEY, ) # Creating an instance of a raw master key test_raw_master_key = RawMasterKey( key_id=test_raw_aes_keyring.key_name, provider_id=test_raw_aes_keyring.key_namespace, wrapping_key=test_raw_aes_keyring._wrapping_key_structure, ) # Encrypt using raw AES keyring encryption_materials = test_raw_aes_keyring.on_encrypt( encryption_materials=encryption_materials_samples) # Check if plaintext data key encrypted by raw keyring is decrypted by raw master key raw_mkp_decrypted_data_key = test_raw_master_key.decrypt_data_key_from_list( encrypted_data_keys=encryption_materials._encrypted_data_keys, algorithm=encryption_materials.algorithm, encryption_context=encryption_materials.encryption_context, ).data_key assert encryption_materials.data_encryption_key.data_key == raw_mkp_decrypted_data_key
def get_multi_keyring_with_generator_and_children(): private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) return MultiKeyring( generator=RawAESKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_key=_WRAPPING_KEY_AES, ), children=[ RawRSAKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1, private_wrapping_key=private_key, public_wrapping_key=private_key.public_key(), ), RawRSAKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1, private_wrapping_key=private_key, public_wrapping_key=private_key.public_key(), ), ], )
def test_invalid_parameters(key_namespace, key_name, wrapping_algorithm, wrapping_key): with pytest.raises(TypeError): RawAESKeyring( key_namespace=key_namespace, key_name=key_name, wrapping_key=wrapping_key, )
def run(source_plaintext): # type: (bytes) -> None """Demonstrate an encrypt/decrypt cycle using a raw AES keyring. :param bytes source_plaintext: Plaintext to encrypt """ # Prepare your encryption context. # 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", } # Generate a 256-bit (32 byte) AES key to use with your keyring. # # In practice, you should get this key from a secure key management system such as an HSM. key = os.urandom(32) # Create the keyring that determines how your data keys are protected. keyring = RawAESKeyring( # 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. # # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring key_namespace="some managed raw keys", key_name=b"my AES wrapping key", wrapping_key=key, ) # Encrypt your plaintext data. ciphertext, _encrypt_header = aws_encryption_sdk.encrypt( source=source_plaintext, encryption_context=encryption_context, keyring=keyring ) # Demonstrate that the ciphertext and plaintext are different. assert ciphertext != source_plaintext # 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) # Demonstrate that the decrypted plaintext is identical to the original plaintext. assert decrypted == source_plaintext # 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())
def test_keyring_with_generator_but_no_children(): generator_keyring = RawAESKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_key=_WRAPPING_KEY_AES, ) test_multi_keyring = MultiKeyring(generator=generator_keyring) assert test_multi_keyring.generator is generator_keyring assert not test_multi_keyring.children
def test_invalid_key_length(): with pytest.raises(ValueError) as excinfo: RawAESKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_key=b"012345", ) excinfo.match( r"Invalid wrapping key length. Must be one of \[16, 24, 32\] bytes.")
def test_keyring_with_children_but_no_generator(): children_keyring = [ RawAESKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_key=_WRAPPING_KEY_AES, ) ] test_multi_keyring = MultiKeyring(children=children_keyring) assert test_multi_keyring.children is children_keyring assert test_multi_keyring.generator is None
def test_raw_keyring_decrypts_what_raw_master_key_encrypts( encryption_materials_samples): # Initializing attributes key_namespace = _PROVIDER_ID key_name = _KEY_ID # Creating an instance of a raw AES keyring test_raw_aes_keyring = RawAESKeyring( key_namespace=key_namespace, key_name=key_name, wrapping_key=_WRAPPING_KEY, ) # Creating an instance of a raw master key test_raw_master_key = RawMasterKey( key_id=test_raw_aes_keyring.key_name, provider_id=test_raw_aes_keyring.key_namespace, wrapping_key=test_raw_aes_keyring._wrapping_key_structure, ) if encryption_materials_samples.data_encryption_key is None: return raw_master_key_encrypted_data_key = test_raw_master_key.encrypt_data_key( data_key=encryption_materials_samples.data_encryption_key, algorithm=encryption_materials_samples.algorithm, encryption_context=encryption_materials_samples.encryption_context, ) # Check if plaintext data key encrypted by raw master key is decrypted by raw keyring raw_aes_keyring_decrypted_data_key = test_raw_aes_keyring.on_decrypt( decryption_materials=DecryptionMaterials( algorithm=encryption_materials_samples.algorithm, encryption_context=encryption_materials_samples.encryption_context, verification_key=b"ex_verification_key", ), encrypted_data_keys=[raw_master_key_encrypted_data_key], ).data_encryption_key.data_key assert encryption_materials_samples.data_encryption_key.data_key == raw_aes_keyring_decrypted_data_key
def ephemeral_raw_aes_keyring( wrapping_algorithm=WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING, key=None): # type: (WrappingAlgorithm, Optional[bytes]) -> RawAESKeyring key_length = wrapping_algorithm.algorithm.data_key_len if key is None: key = os.urandom(key_length) return RawAESKeyring( key_namespace="fake", key_name="aes-{}".format(key_length * 8).encode("utf-8"), wrapping_key=key, )
def raw_aes_keyring(): return RawAESKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_key=_WRAPPING_KEY, )
b'*!\xa1"^-(\xf3\x105\x05i@B\xc2\xa2\xb7\xdd\xd5\xd5\xa9\xddm\xfae\xa8\\$\xf9d\x1e(', ), encryption_context=_ENCRYPTION_CONTEXT, keyring_trace=[ KeyringTrace( wrapping_key=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_KEY_ID), flags={KeyringTraceFlag.GENERATED_DATA_KEY}, ) ], ) _MULTI_KEYRING_WITH_GENERATOR_AND_CHILDREN = MultiKeyring( generator=RawAESKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_key=_WRAPPING_KEY_AES, ), children=[ RawRSAKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID, wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1, private_wrapping_key=rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend()), ), RawRSAKeyring( key_namespace=_PROVIDER_ID, key_name=_KEY_ID,