in src/dynamodb_encryption_sdk/encrypted/item.py [0:0]
def decrypt_dynamodb_item(item, crypto_config):
# type: (dynamodb_types.ITEM, CryptoConfig) -> dynamodb_types.ITEM
"""Decrypt a DynamoDB item.
>>> from dynamodb_encryption_sdk.encrypted.item import decrypt_python_item
>>> encrypted_item = {
... 'some': {'B': b'ENCRYPTED_DATA'},
... 'more': {'B': b'ENCRYPTED_DATA'}
... }
>>> decrypted_item = decrypt_python_item(
... item=encrypted_item,
... crypto_config=my_crypto_config
... )
.. note::
This handles DynamoDB-formatted items and is for use with the boto3 DynamoDB client.
:param dict item: Encrypted and signed DynamoDB item
:param CryptoConfig crypto_config: Cryptographic configuration
:returns: Plaintext DynamoDB item
:rtype: dict
"""
unique_actions = set([crypto_config.attribute_actions.default_action.name])
unique_actions.update({action.name for action in crypto_config.attribute_actions.attribute_actions.values()})
if crypto_config.attribute_actions.take_no_actions:
# If we explicitly have been told not to do anything to this item, just copy it.
return item.copy()
try:
signature_attribute = item.pop(ReservedAttributes.SIGNATURE.value)
except KeyError:
# The signature is always written, so if no signature is found then the item was not
# encrypted or signed.
raise DecryptionError("No signature attribute found in item")
inner_crypto_config = crypto_config.copy()
# Retrieve the material description from the item if found.
try:
material_description_attribute = item.pop(ReservedAttributes.MATERIAL_DESCRIPTION.value)
except KeyError:
# If no material description is found, we use inner_crypto_config as-is.
pass
else:
# If material description is found, override the material description in inner_crypto_config.
material_description = deserialize_material_description(material_description_attribute)
inner_crypto_config.encryption_context.material_description = material_description
decryption_materials = inner_crypto_config.decryption_materials()
verify_item_signature(signature_attribute, item, decryption_materials.verification_key, inner_crypto_config)
try:
decryption_key = decryption_materials.decryption_key
except AttributeError:
if inner_crypto_config.attribute_actions.contains_action(CryptoAction.ENCRYPT_AND_SIGN):
raise DecryptionError(
"Attribute actions ask for some attributes to be decrypted but no decryption key is available"
)
return item.copy()
decryption_mode = inner_crypto_config.encryption_context.material_description.get(
MaterialDescriptionKeys.ATTRIBUTE_ENCRYPTION_MODE.value
)
algorithm_descriptor = decryption_key.algorithm + decryption_mode
# Once the signature has been verified, actually decrypt the item attributes.
decrypted_item = {}
for name, attribute in item.items():
if inner_crypto_config.attribute_actions.action(name) is CryptoAction.ENCRYPT_AND_SIGN:
decrypted_item[name] = decrypt_attribute(
attribute_name=name, attribute=attribute, decryption_key=decryption_key, algorithm=algorithm_descriptor
)
else:
decrypted_item[name] = attribute.copy()
return decrypted_item