Ejemplo n.º 1
0
def _build_kms_cmp(require_attributes):
    inner_cmp = AwsKmsCryptographicMaterialsProvider(key_id=cmk_arn_value())
    if require_attributes:
        return functional_test_utils.PassThroughCryptographicMaterialsProviderThatRequiresAttributes(
            inner_cmp)
    else:
        return inner_cmp
Ejemplo n.º 2
0
class CryptoItems:
    with open('aws') as v:
        aws_access_key_id = str(v.readline().strip())
        aws_secret_access_key = str(v.readline().strip())

    dbResource = boto3.resource('dynamodb',
                                aws_access_key_id=aws_access_key_id,
                                aws_secret_access_key=aws_secret_access_key,
                                region_name='us-east-1').Table('Users')

    # crypto key and material provider
    aws_cmk_id = 'arn:aws:kms:us-east-1:910140038075:key/353f6f4c-0d0b-47b1-99fc-3aeec929b973'
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    # how the crypto is applied to attributes
    crypto_actions = AttributeActions(
        default_action=CryptoAction.DO_NOTHING,
        attribute_actions={'password': CryptoAction.ENCRYPT_AND_SIGN})

    crypto_context = EncryptionContext(table_name='Users')

    custom_crypto_config = CryptoConfig(materials_provider=aws_kms_cmp,
                                        attribute_actions=crypto_actions,
                                        encryption_context=crypto_context)

    encrypted_resource = EncryptedTable(table=dbResource,
                                        materials_provider=aws_kms_cmp,
                                        attribute_actions=crypto_actions)
Ejemplo n.º 3
0
def encrypt_item(table_name, aws_cmk_id, meta_table_name, material_name):
    """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 for the meta store.
    meta_table = boto3.resource("dynamodb").Table(meta_table_name)
    # Create a crypto materials provider for the meta store using the specified AWS KMS key.
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)
    # Create a meta store using the AWS KMS crypto materials provider.
    meta_store = MetaStore(table=meta_table, materials_provider=aws_kms_cmp)
    # Create a most recent provider using the meta store.
    most_recent_cmp = MostRecentProvider(
        provider_store=meta_store,
        material_name=material_name,
        version_ttl=600.0,  # Check for a new material version every five minutes.
    )
    # Create a normal table resource.
    table = boto3.resource("dynamodb").Table(table_name)
    # 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=most_recent_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)
def _kms_cmp(**custom_kwargs):
    kwargs = dict(key_id="test_key_id", botocore_session=botocore.session.Session())
    kwargs.update(custom_kwargs)
    if isinstance(kwargs.get("regional_clients", None), dict):
        for region, client in kwargs["regional_clients"].items():
            if client == "generate client":
                kwargs["regional_clients"][region] = boto3.client("kms", region="us-west-2")
    return AwsKmsCryptographicMaterialsProvider(**kwargs)
def _kms_cmp(**custom_kwargs):
    kwargs = dict(key_id='test_key_id',
                  botocore_session=botocore.session.Session())
    kwargs.update(custom_kwargs)
    if isinstance(kwargs.get('regional_clients', None), dict):
        for region, client in kwargs['regional_clients'].items():
            if client == 'generate client':
                kwargs['regional_clients'][region] = boto3.client(
                    'kms', region='us-west-2')
    return AwsKmsCryptographicMaterialsProvider(**kwargs)
def test_kms_cmp_values_set(kwargs):
    cmp = AwsKmsCryptographicMaterialsProvider(key_id="example_key_id", **kwargs)

    assert cmp._key_id == "example_key_id"

    if "botocore_session" in kwargs:
        assert cmp._botocore_session == kwargs["botocore_session"]

    assert cmp._grant_tokens == kwargs.get("grant_tokens", ())
    assert cmp._material_description == kwargs.get("material_description", {})
    assert cmp._regional_clients == kwargs.get("regional_clients", {})
def encrypt_item(table_name, aws_cmk_id):
    """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)
    # 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 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=aws_kms_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)
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)
Ejemplo n.º 9
0
def fetch_user_info(username, data, awsCmkId, table):
    kmsCmp = AwsKmsCryptographicMaterialsProvider(key_id=awsCmkId)
    actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN
    )
    encrypted_table = EncryptedTable(table=table, materials_provider=kmsCmp, attribute_actions=actions)

    resp = encrypted_table.get_item(
        Key = {'USERNAME': username}
    )

    user = resp['Item']

    info = user[data]

    return info
Ejemplo n.º 10
0
def get_decrypted_item(index_key, table_name):
    table = boto3.resource('dynamodb').Table(table_name)

    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={'Account_Id': CryptoAction.DO_NOTHING})

    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=aws_kms_cmp,
                                     attribute_actions=actions)

    response = encrypted_table.get_item(Key=index_key)

    return response
def encrypt_item(USERNAME, PASSWORD, FIRST_NAME, MIDDLE_INITIAL, LAST_NAME,
                 DOB, SEX, HEIGHT, WEIGHT, ALLERGIES, TOKEN, awsCmkId, table):

    kmsCmp = AwsKmsCryptographicMaterialsProvider(key_id=awsCmkId)
    actions = AttributeActions(default_action=CryptoAction.ENCRYPT_AND_SIGN)

    index_key = {}

    plaintext_item = {
        'USERNAME': USERNAME,
        'PASSWORD': PASSWORD,
        'FIRST_NAME': FIRST_NAME,
        'MIDDLE_INITIAL': MIDDLE_INITIAL,
        'LAST_NAME': LAST_NAME,
        'DOB': DOB,
        'SEX': SEX,
        'HEIGHT': HEIGHT,
        'WEIGHT': WEIGHT,
        'ALLERGIES': ALLERGIES,
        'AUTH_TOKEN': TOKEN
    }

    encrypted_attributes = set(plaintext_item.keys())

    unencrypted_attributes = set(index_key.keys())

    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=kmsCmp,
                                     attribute_actions=actions)
    encrypted_table.put_item(Item=plaintext_item)

    encrypted_item = table.get_item(Key={'USERNAME': USERNAME})["Item"]
    decrypted_item = encrypted_table.get_item(
        Key={'USERNAME': USERNAME})["Item"]

    # Verify that all of the attributes are different in the encrypted item
    for name in encrypted_attributes:
        if name != 'USERNAME':
            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]
Ejemplo n.º 12
0
def encrypt_item(plaintext_item, table_name):
    table = boto3.resource('dynamodb').Table(table_name)

    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={'Account_Id': CryptoAction.DO_NOTHING})

    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=aws_kms_cmp,
                                     attribute_actions=actions)

    print(plaintext_item)
    response = encrypted_table.put_item(Item=plaintext_item)

    print(response)
    return response
def get_decrypted_item(index_key, table_name):
    #table_name='CreditCardTokenizerTable'
    table = boto3.resource('dynamodb').Table(table_name)

    aws_cmk_id = 'arn:aws:kms:us-west-2:176385768664:key/bd3a8796-1638-42f3-b318-ac357427f326'
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={'Account_Id': CryptoAction.DO_NOTHING})

    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=aws_kms_cmp,
                                     attribute_actions=actions)

    response = encrypted_table.get_item(Key=index_key)

    return response
def fetch_user(username, awsCmkId, table):
    try:
        kmsCmp = AwsKmsCryptographicMaterialsProvider(key_id=awsCmkId)
        actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN
        )

        encrypted_table = EncryptedTable(table=table, materials_provider=kmsCmp, attribute_actions=actions)

        #gets decrypted info from encrypted table
        response = encrypted_table.get_item(
        Key = {'USERNAME': username}
        )
        
        item = response['Item']
        return item

    except Exception as e:
        print("in get_user.py: Exception. Could not get user from database. " + str(e))
        return -1
        
Ejemplo n.º 15
0
def encrypt_batch_items(table_name, aws_cmk_id):
    """Demonstrate use of EncryptedResource to transparently encrypt multiple items in a batch request."""
    index_keys = [
        {"partition_attribute": "is this", "sort_attribute": 55},
        {"partition_attribute": "is this", "sort_attribute": 56},
        {"partition_attribute": "is this", "sort_attribute": 57},
        {"partition_attribute": "another", "sort_attribute": 55},
    ]
    plaintext_additional_attributes = {
        "example": "data",
        "some numbers": 99,
        "and some binary": Binary(b"\x00\x01\x02"),
        "leave me": "alone",  # We want to ignore this attribute
    }
    plaintext_items = []
    for key in index_keys:
        _attributes = key.copy()
        _attributes.update(plaintext_additional_attributes)
        plaintext_items.append(_attributes)

    # Collect all of the attributes that will be encrypted (used later).
    encrypted_attributes = set(plaintext_additional_attributes.keys())
    encrypted_attributes.remove("leave me")
    # Collect all of the attributes that will not be encrypted (used later).
    unencrypted_attributes = set(index_keys[0].keys())
    unencrypted_attributes.add("leave me")

    # Create a normal service resource.
    resource = boto3.resource("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 resource 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 service resource.
    encrypted_resource = EncryptedResource(resource=resource, materials_provider=aws_kms_cmp, attribute_actions=actions)

    # Put the items to the table, using the encrypted service resource to transparently encrypt them.
    encrypted_resource.batch_write_item(
        RequestItems={table_name: [{"PutRequest": {"Item": item}} for item in plaintext_items]}
    )

    # Get the encrypted item using the standard service resource.
    encrypted_items = resource.batch_get_item(RequestItems={table_name: {"Keys": index_keys}})["Responses"][table_name]

    # Get the item using the encrypted service resource, transparently decyrpting it.
    decrypted_items = encrypted_resource.batch_get_item(RequestItems={table_name: {"Keys": index_keys}})["Responses"][
        table_name
    ]

    def _select_index_from_item(item):
        """Find the index keys that match this item."""
        for index in index_keys:
            if all([item[key] == value for key, value in index.items()]):
                return index

    def _select_item_from_index(index, all_items):
        """Find the item that matches these index keys."""
        for item in all_items:
            if all([item[key] == value for key, value in index.items()]):
                return item

    for encrypted_item in encrypted_items:
        key = _select_index_from_item(encrypted_item)
        plaintext_item = _select_item_from_index(key, plaintext_items)
        decrypted_item = _select_item_from_index(key, decrypted_items)

        # 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_resource.batch_write_item(
        RequestItems={table_name: [{"DeleteRequest": {"Key": key}} for key in index_keys]}
    )
Ejemplo n.º 16
0
def signup_login(request):
	global input_folder,output_folder
	for the_file in os.listdir(input_folder):
	    file_path = os.path.join(input_folder, the_file)
	    try:
	        if os.path.isfile(file_path):
	            os.unlink(file_path)
	    except Exception as e:
	        print(e)
	for the_file in os.listdir(output_folder):
	    file_path = os.path.join(output_folder, the_file)
	    try:
	        if os.path.isfile(file_path):
	            os.unlink(file_path)
	    except Exception as e:
	        print(e)
	if request.method == 'GET':
		return render(request,'index.html')
	if request.method == 'POST':
    	 dynamodb = boto3.resource('dynamodb',region_name='us-east-1')
    	 table = dynamodb.Table('users')
    	 aws_cmk_id=''
    	 aws_kms_cmp=AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)
    	 name2 = request.POST['login']
    	 name3=str(name2)
    	 actions = AttributeActions(
				    #default_action=CryptoAction.ENCRYPT_AND_SIGN,
				    default_action=CryptoAction.DO_NOTHING,
				    attribute_actions={
				    	'userid': CryptoAction.DO_NOTHING,
				        'first_name': CryptoAction.DO_NOTHING,
				        'last_name': CryptoAction.DO_NOTHING,
				        'password':CryptoAction.ENCRYPT_AND_SIGN
				        
				    }
				  )
    	 encrypted_table = EncryptedTable(
					    table=table,
					    materials_provider=aws_kms_cmp,
					    attribute_actions=actions
					)
    	 #signup='signup'
    	 #login='******'
    	 print("check*****",name2)
    	 if(name2=='send'):
    	 	 return render(request,"upload.html")
    	 if(name2=='signup'):
             	first_name=request.POST.get('first','')
             	last_name=request.POST.get('last','')
             	email = request.POST.get('newemail','')
             	password = request.POST.get('newpassword','')
             	print ("first name is ", first_name, "last name is ", last_name)
             	encrypted_table.put_item(Item={
	                        'userid': email,
	                        'first_name': first_name,
	                        'last_name': last_name,
	                        'password': password,
	                    })
             	logger.info('User Sign Up: {} - {}'.format(first_name,email))
             	return render(request,"upload.html")
    	 if(name2=='login'):
             email = request.POST.get('username','')
             password = request.POST.get('password','')
             print ("username is ", email, "password is ", password)
             email=str(email)
             password=str(password)
             s=''
             s=email+password
             response= encrypted_table.get_item(Key={
                        'userid': email
                    })
             if(len(response)==2): 
                item = response['Item']['password']
                if(password==item):
                	logger.info('Succesful Log-In: {}'.format(email))
                	return render(request,"upload.html")
                else:
                	logger.info('Unsuccesful Log-In(Password Invalid): {}'.format(email))
                	print("Invalid password")
                	return render(request,'index.html',{'s':["invalid password",'0']})
             else:
                print("Invalid Username")
                logger.info('Unsuccesful Log-In(Username Invalid): {}'.format(email))
                s1="invalid username"
                return render(request,'index.html',{'s':["invalid username",'0']})
Ejemplo n.º 17
0
class User:
    db = boto3.resource("dynamodb").Table(config.DB_TABLE_NAME)
    secrets_table_name = boto3.resource("dynamodb").Table(config.SECRETS_TABLE_NAME)
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(config.DB_ENCRYPTION_KEY_ALIAS)


    secrets_table = EncryptedTable(
        table=secrets_table_name,
        materials_provider=aws_kms_cmp
    )

    pywaves.setNode(config.NODE_URL, config.NET_ID)
    pywaves.setThrowOnError()

    def __init__(self, user_id, seed=""):
        self.user_id = user_id
        if seed:
            self.seed = seed
            self.create_wallet(seed)
        else:
            self.initialise_wallet()

    @classmethod
    def retrieve(cls, user_id):
        """
        Creates a new User object by retrieving the user_id from database
        If the user_id does not exist in the database then this method
        will throw a KeyError
        """
        user = cls.db.get_item(Key={"user_id": str(user_id)})["Item"]
        seed = cls.retrieve_wallet(str(user["wallet_guid"]))
        return User(user_id=user["user_id"], seed=seed)

    def initialise_wallet(self):
        self.wallet_guid = str(uuid.uuid4())

        self.seed = pywaves.Address().seed 
        self.create_wallet(self.seed)
        self.secrets_table.put_item(
            Item={ "guid": self.wallet_guid, 
                   "seed": self.seed }
        )
        self.db.put_item(
            Item={"user_id": str(self.user_id), "wallet_guid": self.wallet_guid }
        )

    def create_wallet(self, seed=""):
        """
        Initializes the pywaves wallet for the User object.
        If seed is provided, the wallet is initialized from the seed,
        otherwise a wallet is generated from a new seed.
        """
        self.wallet = pywaves.Address(seed=seed)

    @classmethod 
    def retrieve_wallet(cls, wallet_guid):
        """
        Retrieves the wallet seed for the user from the encrypted secrets table
        """
        return cls.secrets_table.get_item(
           Key={"guid": wallet_guid} 
        )["Item"]["seed"]
Ejemplo n.º 18
0
def encrypt_item(table_name, aws_cmk_id):
    """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)

    # Use the TableInfo helper to collect information about the indexes.
    table_info = TableInfo(name=table_name)
    table_info.refresh_indexed_attributes(table.meta.client)

    # Create a crypto materials provider using the specified AWS KMS key.
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    encryption_context = EncryptionContext(
        table_name=table_name,
        partition_key_name=table_info.primary_index.partition,
        sort_key_name=table_info.primary_index.sort,
        # The only attributes that are used by the AWS KMS cryptographic materials providers
        # are the primary index attributes.
        # These attributes need to be in the form of a DynamoDB JSON structure, so first
        # convert the standard dictionary.
        attributes=dict_to_ddb(index_key)
    )

    # Create attribute actions that tells the encrypted table to encrypt all attributes,
    # only sign the primary index attributes, and ignore the one identified attribute to
    # ignore.
    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={'leave me': CryptoAction.DO_NOTHING}
    )
    actions.set_index_keys(*table_info.protected_index_keys())

    # Build the crypto config to use for this item.
    # When using the higher-level helpers, this is handled for you.
    crypto_config = CryptoConfig(
        materials_provider=aws_kms_cmp,
        encryption_context=encryption_context,
        attribute_actions=actions
    )

    # Encrypt the plaintext item directly
    encrypted_item = encrypt_python_item(plaintext_item, crypto_config)

    # You could now put the encrypted item to DynamoDB just as you would any other item.
    # table.put_item(Item=encrypted_item)
    # We will skip this for the purposes of this example.

    # Decrypt the encrypted item directly
    decrypted_item = decrypt_python_item(encrypted_item, crypto_config)

    # 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]
def aws_kms_cmp():
    return AwsKmsCryptographicMaterialsProvider(key_id=cmk_arn())
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)
Ejemplo n.º 21
0
def _build_aws_kms_cmp(decrypt_key, verify_key):
    key_id = decrypt_key["keyId"]
    return AwsKmsCryptographicMaterialsProvider(key_id=key_id)
Ejemplo n.º 22
0
        ],
        AttributeDefinitions=[
            {"AttributeName": "pk", "AttributeType": "S"},
            {"AttributeName": "sk", "AttributeType": "S"},
        ],
        BillingMode="PAY_PER_REQUEST",
    )
    print(f"Waiting for table session_data...")
    waiter = client.get_waiter("table_exists")
    waiter.wait(TableName=table_name)

table = boto3.resource("dynamodb").Table(table_name)

# Create a KMS provider. Pass in a valid KMS customer master key.
aws_cmk_id = "1234abcd-12ab-34cd-56ef-1234567890ab"  # YOUR CMK HERE
aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

# Tell the encrypted table to encrypt and sign all attributes except one.
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={"test": CryptoAction.DO_NOTHING},
)

# Use these objects to create an encrypted table resource.
encrypted_table = EncryptedTable(
    table=table, materials_provider=aws_kms_cmp, attribute_actions=actions
)

# Add an item to the table

plaintext_item = {