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
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)
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)
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
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]
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
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]} )
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']})
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"]
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)
def _build_aws_kms_cmp(decrypt_key, verify_key): key_id = decrypt_key["keyId"] return AwsKmsCryptographicMaterialsProvider(key_id=key_id)
], 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 = {