def _build_wrapped_cmp(encrypt_key, decrypt_key, sign_key, verify_key): wrapping_key = _load_key(encrypt_key) unwrapping_key = _load_key(decrypt_key) signing_key = _load_signing_key(sign_key) return WrappedCryptographicMaterialsProvider(signing_key=signing_key, unwrapping_key=unwrapping_key, wrapping_key=wrapping_key)
def get_or_create_provider(self, material_name, version): # type: (Text, int) -> CryptographicMaterialsProvider """Obtain a cryptographic materials provider identified by a name and version. If the requested version does not exist, a new one will be created. :param str material_name: Material to locate :param int version: Version of material to locate :returns: cryptographic materials provider :rtype: CryptographicMaterialsProvider :raises InvalidVersionError: if the requested version is not available and cannot be created """ encryption_key = JceNameLocalDelegatedKey.generate( MetaStoreValues.ENCRYPTION_ALGORITHM.value, MetaStoreValues.KEY_BITS.value) signing_key = JceNameLocalDelegatedKey.generate( MetaStoreValues.INTEGRITY_ALGORITHM.value, MetaStoreValues.KEY_BITS.value) encryption_key, signing_key = self._save_or_load_materials( material_name, version, encryption_key, signing_key) return WrappedCryptographicMaterialsProvider( signing_key=signing_key, wrapping_key=encryption_key, unwrapping_key=encryption_key, material_description=self._material_description( material_name, version), )
def wrapped_cmp(): wrapping_key = JceNameLocalDelegatedKey.generate("AES", 256) signing_key = JceNameLocalDelegatedKey.generate("HmacSHA512", 256) cmp = WrappedCryptographicMaterialsProvider(signing_key=signing_key, wrapping_key=wrapping_key, unwrapping_key=wrapping_key) return cmp
def _build_wrapped_jce_cmp(wrapping_algorithm, wrapping_key_length, signing_algorithm, signing_key_length): """Build a WrappedCryptographicMaterialsProvider using ephemeral JceNameLocalDelegatedKeys as specified.""" wrapping_key = _get_from_cache(JceNameLocalDelegatedKey, wrapping_algorithm, wrapping_key_length) signing_key = _get_from_cache(JceNameLocalDelegatedKey, signing_algorithm, signing_key_length) return WrappedCryptographicMaterialsProvider( wrapping_key=wrapping_key, unwrapping_key=wrapping_key, signing_key=signing_key )
def test_key_generation(client): collection = client.db.key_store key_bytes = os.urandom(32) wrapping_key = JceNameLocalDelegatedKey( key=key_bytes, algorithm="AES", key_type=EncryptionKeyType.SYMMETRIC, key_encoding=KeyEncodingType.RAW, ) signing_key = JceNameLocalDelegatedKey( key=key_bytes, algorithm="HmacSHA512", key_type=EncryptionKeyType.SYMMETRIC, key_encoding=KeyEncodingType.RAW, ) wrapped_cmp = WrappedCryptographicMaterialsProvider( wrapping_key=wrapping_key, unwrapping_key=wrapping_key, signing_key=signing_key, ) key_store = MongodbKeyStore(collection=collection, materials_provider=wrapped_cmp) key_id = "key1" new_main_key = key_store.create_main_key(key_id) main_key = key_store.get_main_key(key_id) assert main_key.key_id == new_main_key.key_id assert main_key.key_bytes == new_main_key.key_bytes
def test_no_materials(method, error_type, message): empty_cmp = WrappedCryptographicMaterialsProvider(signing_key=MagicMock( __class__=DelegatedKey)) with pytest.raises(error_type) as excinfo: getattr(empty_cmp, method)(EncryptionContext()) excinfo.match(message)
def test_build_materials(mocker): mocker.patch.object(dynamodb_encryption_sdk.material_providers.wrapped, 'WrappedCryptographicMaterials') cmp = WrappedCryptographicMaterialsProvider( signing_key=MagicMock(__class__=DelegatedKey), wrapping_key=MagicMock(__class__=DelegatedKey), unwrapping_key=MagicMock(__class__=DelegatedKey)) material_description = {'some': 'data'} context = EncryptionContext(material_description=material_description) test = cmp._build_materials(context) dynamodb_encryption_sdk.material_providers.wrapped.WrappedCryptographicMaterials.assert_called_once_with( wrapping_key=cmp._wrapping_key, unwrapping_key=cmp._unwrapping_key, signing_key=cmp._signing_key, material_description=material_description) assert test is dynamodb_encryption_sdk.material_providers.wrapped.WrappedCryptographicMaterials.return_value
def test_valid_materials(mocker, method): mocker.patch.object(WrappedCryptographicMaterialsProvider, '_build_materials') cmp = WrappedCryptographicMaterialsProvider( signing_key=MagicMock(__class__=DelegatedKey), wrapping_key=MagicMock(__class__=DelegatedKey), unwrapping_key=MagicMock(__class__=DelegatedKey)) context = EncryptionContext() test = getattr(cmp, method)(context) WrappedCryptographicMaterialsProvider._build_materials.assert_called_once_with( context) assert test is WrappedCryptographicMaterialsProvider._build_materials.return_value
def _load_provider_from_table(self, material_name, version): # type: (Text, int) -> CryptographicMaterialsProvider """Load a provider from the table. If the requested version does not exist, an error will be raised. :param str material_name: Material to locate :param int version: Version of material to locate """ encryption_key, signing_key = self._load_materials( material_name, version) return WrappedCryptographicMaterialsProvider( signing_key=signing_key, wrapping_key=encryption_key, unwrapping_key=encryption_key, material_description=self._material_description( material_name, version))
def test_key_generation(): table_name = "key_store" DynamodbKeyStore.create_table( client=boto3.client("dynamodb", region_name="us-east-1"), table_name=table_name, ) table = boto3.resource("dynamodb", region_name="us-east-1").Table(table_name) key_bytes = os.urandom(32) wrapping_key = JceNameLocalDelegatedKey( key=key_bytes, algorithm="AES", key_type=EncryptionKeyType.SYMMETRIC, key_encoding=KeyEncodingType.RAW, ) signing_key = JceNameLocalDelegatedKey( key=key_bytes, algorithm="HmacSHA512", key_type=EncryptionKeyType.SYMMETRIC, key_encoding=KeyEncodingType.RAW, ) wrapped_cmp = WrappedCryptographicMaterialsProvider( wrapping_key=wrapping_key, unwrapping_key=wrapping_key, signing_key=signing_key, ) key_store = DynamodbKeyStore(table=table, materials_provider=wrapped_cmp) key_id = "key1" new_main_key = key_store.create_main_key(key_id) main_key = key_store.get_main_key(key_id) assert main_key.key_id == new_main_key.key_id assert main_key.key_bytes == new_main_key.key_bytes
def create_in_memory_key_store(): key_bytes = os.urandom(32) wrapping_key = JceNameLocalDelegatedKey( key=key_bytes, algorithm="AES", key_type=EncryptionKeyType.SYMMETRIC, key_encoding=KeyEncodingType.RAW, ) signing_key = JceNameLocalDelegatedKey( key=key_bytes, algorithm="HmacSHA512", key_type=EncryptionKeyType.SYMMETRIC, key_encoding=KeyEncodingType.RAW, ) wrapped_cmp = WrappedCryptographicMaterialsProvider( wrapping_key=wrapping_key, unwrapping_key=wrapping_key, signing_key=signing_key, ) key_store = InMemoryKeyStore(materials_provider=wrapped_cmp) return key_store
def test_attrs_fail(invalid_kwargs): kwargs = dict(signing_key=MagicMock(__class__=DelegatedKey)) kwargs.update(invalid_kwargs) with pytest.raises(TypeError): WrappedCryptographicMaterialsProvider(**kwargs)
def encrypt_item(table_name, aes_wrapping_key_bytes, hmac_signing_key_bytes): """Demonstrate use of EncryptedTable to transparently encrypt an item.""" index_key = {"partition_attribute": "is this", "sort_attribute": 55} plaintext_item = { "example": "data", "some numbers": 99, "and some binary": Binary(b"\x00\x01\x02"), "leave me": "alone", # We want to ignore this attribute } # Collect all of the attributes that will be encrypted (used later). encrypted_attributes = set(plaintext_item.keys()) encrypted_attributes.remove("leave me") # Collect all of the attributes that will not be encrypted (used later). unencrypted_attributes = set(index_key.keys()) unencrypted_attributes.add("leave me") # Add the index pairs to the item. plaintext_item.update(index_key) # Create a normal table resource. table = boto3.resource("dynamodb").Table(table_name) # generated code confuse pylint: disable=no-member # Create a crypto materials provider using the provided wrapping and signing keys. wrapping_key = JceNameLocalDelegatedKey( key=aes_wrapping_key_bytes, algorithm="AES", key_type=EncryptionKeyType.SYMMETRIC, key_encoding=KeyEncodingType.RAW, ) signing_key = JceNameLocalDelegatedKey( key=hmac_signing_key_bytes, algorithm="HmacSHA512", key_type=EncryptionKeyType.SYMMETRIC, key_encoding=KeyEncodingType.RAW, ) wrapped_cmp = WrappedCryptographicMaterialsProvider( wrapping_key=wrapping_key, unwrapping_key=wrapping_key, signing_key=signing_key) # Create attribute actions that tells the encrypted table to encrypt all attributes except one. actions = AttributeActions( default_action=CryptoAction.ENCRYPT_AND_SIGN, attribute_actions={"leave me": CryptoAction.DO_NOTHING}) # Use these objects to create an encrypted table resource. encrypted_table = EncryptedTable(table=table, materials_provider=wrapped_cmp, attribute_actions=actions) # Put the item to the table, using the encrypted table resource to transparently encrypt it. encrypted_table.put_item(Item=plaintext_item) # Get the encrypted item using the standard table resource. encrypted_item = table.get_item(Key=index_key)["Item"] # Get the item using the encrypted table resource, transparently decyrpting it. decrypted_item = encrypted_table.get_item(Key=index_key)["Item"] # Verify that all of the attributes are different in the encrypted item for name in encrypted_attributes: assert encrypted_item[name] != plaintext_item[name] assert decrypted_item[name] == plaintext_item[name] # Verify that all of the attributes that should not be encrypted were not. for name in unencrypted_attributes: assert decrypted_item[name] == encrypted_item[name] == plaintext_item[ name] # Clean up the item encrypted_table.delete_item(Key=index_key)