Beispiel #1
0
def client_cycle_single_item_check(materials_provider, initial_actions, initial_item, table_name, region_name=None):
    check_attribute_actions = initial_actions.copy()
    check_attribute_actions.set_index_keys(*list(TEST_KEY.keys()))
    item = initial_item.copy()
    item.update(TEST_KEY)
    ddb_item = dict_to_ddb(item)
    ddb_key = dict_to_ddb(TEST_KEY)

    kwargs = {}
    if region_name is not None:
        kwargs["region_name"] = region_name
    client = boto3.client("dynamodb", **kwargs)
    e_client = EncryptedClient(client=client, materials_provider=materials_provider, attribute_actions=initial_actions)

    _put_result = e_client.put_item(TableName=table_name, Item=ddb_item)  # noqa

    encrypted_result = client.get_item(TableName=table_name, Key=ddb_key, ConsistentRead=True)
    check_encrypted_item(item, ddb_to_dict(encrypted_result["Item"]), check_attribute_actions)

    decrypted_result = e_client.get_item(TableName=table_name, Key=ddb_key, ConsistentRead=True)
    assert ddb_to_dict(decrypted_result["Item"]) == item

    e_client.delete_item(TableName=table_name, Key=ddb_key)
    del item
    del check_attribute_actions
def encrypt_item(table_name, aws_cmk_id):
    """Demonstrate use of EncryptedClient to transparently encrypt an item."""
    index_key = {"partition_attribute": {"S": "is this"}, "sort_attribute": {"N": "55"}}
    plaintext_item = {
        "example": {"S": "data"},
        "some numbers": {"N": "99"},
        "and some binary": {"B": b"\x00\x01\x02"},
        "leave me": {"S": "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 client.
    client = boto3.client("dynamodb")
    # Create a crypto materials provider using the specified AWS KMS key.
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)
    # Create attribute actions that tells the encrypted client 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 client.
    encrypted_client = EncryptedClient(client=client, materials_provider=aws_kms_cmp, attribute_actions=actions)

    # Put the item to the table, using the encrypted client to transparently encrypt it.
    encrypted_client.put_item(TableName=table_name, Item=plaintext_item)

    # Get the encrypted item using the standard client.
    encrypted_item = client.get_item(TableName=table_name, Key=index_key)["Item"]

    # Get the item using the encrypted client, transparently decyrpting it.
    decrypted_item = encrypted_client.get_item(TableName=table_name, 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_client.delete_item(TableName=table_name, Key=index_key)
def encrypt_item(table_name, cmk_mrk_arn_first_region,
                 cmk_mrk_arn_second_region):
    """Demonstrate use of Multi-Region Keys with DynamoDB Encryption Client.

    This example encrypts an item with a Multi-Region Key in one region and decrypts it in another region. It
    assumes that you have a Dynamo DB Global table in two regions, as well as a KMS
    Multi-Region Key replicated to these regions.
    """
    index_key = {
        "partition_attribute": {
            "S": "is this"
        },
        "sort_attribute": {
            "N": "55"
        }
    }
    plaintext_item = {
        "example": {
            "S": "data"
        },
        "some numbers": {
            "N": "99"
        },
        "and some binary": {
            "B": b"\x00\x01\x02"
        },
        "leave me": {
            "S": "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 attribute actions that tells the encrypted client to encrypt all attributes except one.
    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={"leave me": CryptoAction.DO_NOTHING})

    # Create a DDB client and KMS crypto materials provider in the first region using the specified AWS KMS key.
    split_arn = cmk_mrk_arn_first_region.split(":")
    encryption_region = split_arn[3]
    ddb_client = boto3.client("dynamodb", region_name=encryption_region)
    encryption_cmp = AwsKmsCryptographicMaterialsProvider(
        key_id=cmk_mrk_arn_first_region)
    # Use these objects to create an encrypted client.
    encryption_client = EncryptedClient(client=ddb_client,
                                        materials_provider=encryption_cmp,
                                        attribute_actions=actions)

    # Put the item to the table, using the encrypted client to transparently encrypt it.
    encryption_client.put_item(TableName=table_name, Item=plaintext_item)

    # Create a DDB client and KMS crypto materials provider in the second region
    split_arn = cmk_mrk_arn_second_region.split(":")
    decryption_region = split_arn[3]
    decryption_cmp = AwsKmsCryptographicMaterialsProvider(
        key_id=cmk_mrk_arn_second_region)
    ddb_client = boto3.client("dynamodb", region_name=decryption_region)
    # Use these objects to create an encrypted client.
    decryption_client = EncryptedClient(client=ddb_client,
                                        materials_provider=decryption_cmp,
                                        attribute_actions=actions)

    # DDB Global Table replication takes some time. Sleep for a moment to give the item a chance to replicate to the
    # second region
    time.sleep(1)

    # Get the item from the second region, transparently decrypting it. This allows you to avoid a cross-region KMS
    # call to the first region if your application is running in the second region
    decrypted_item = decryption_client.get_item(TableName=table_name,
                                                Key=index_key)["Item"]

    # Verify that the decryption successfully retrieved the original plaintext
    for name in encrypted_attributes:
        assert plaintext_item[name] == decrypted_item[name]

    # Clean up the item
    encryption_client.delete_item(TableName=table_name, Key=index_key)