def test_validate_encryption(self): # Arrange self.bbs.require_encryption = True kek = KeyWrapper('key1') self.bbs.key_encryption_key = kek blob_name = self._create_small_blob('block_blob') # Act self.bbs.require_encryption = False self.bbs.key_encryption_key = None blob = self.bbs.get_blob_to_bytes(self.container_name, blob_name) encryption_data = _dict_to_encryption_data( loads(blob.metadata['encryptiondata'])) iv = encryption_data.content_encryption_IV content_encryption_key = _validate_and_unwrap_cek( encryption_data, kek, None) cipher = _generate_AES_CBC_cipher(content_encryption_key, iv) decryptor = cipher.decryptor() unpadder = PKCS7(128).unpadder() content = decryptor.update(blob.content) + decryptor.finalize() content = unpadder.update(content) + unpadder.finalize() self.assertEqual(self.bytes, content)
def test_validate_encryption(self): # Arrange self.bbs.require_encryption = True kek = KeyWrapper('key1') self.bbs.key_encryption_key = kek blob_name = self._create_small_blob('block_blob') # Act self.bbs.require_encryption = False self.bbs.key_encryption_key = None blob = self.bbs.get_blob_to_bytes(self.container_name, blob_name) encryption_data = _dict_to_encryption_data(loads(blob.metadata['encryptiondata'])) iv = encryption_data.content_encryption_IV content_encryption_key = _validate_and_unwrap_cek(encryption_data, kek, None) cipher = _generate_AES_CBC_cipher(content_encryption_key, iv) decryptor = cipher.decryptor() unpadder = PKCS7(128).unpadder() content = decryptor.update(blob.content) + decryptor.finalize() content = unpadder.update(content) + unpadder.finalize() self.assertEqual(self.bytes, content)
def test_validate_encryption(self): # Arrange entity = self._create_default_entity_for_encryption() key_encryption_key = KeyWrapper('key1') self.ts.key_encryption_key = key_encryption_key self.ts.insert_entity(self.table_name, entity) # Act self.ts.key_encryption_key = None entity = self.ts.get_entity(self.table_name, entity['PartitionKey'], entity['RowKey']) # Note the minor discrepancy from the normal decryption process: because the entity was retrieved # without being decrypted, the encrypted_properties list is now stored in an EntityProperty object # and is already raw bytes. encrypted_properties_list = entity['_ClientEncryptionMetadata2'].value encryption_data = entity['_ClientEncryptionMetadata1'] encryption_data = _dict_to_encryption_data(loads(encryption_data)) content_encryption_key = key_encryption_key.unwrap_key(encryption_data.wrapped_content_key.encrypted_key, encryption_data.wrapped_content_key.algorithm) digest = Hash(SHA256(), default_backend()) digest.update(encryption_data.content_encryption_IV + (entity['RowKey'] + entity['PartitionKey'] + '_ClientEncryptionMetadata2').encode('utf-8')) metadataIV = digest.finalize() metadataIV = metadataIV[:16] cipher = _generate_AES_CBC_cipher(content_encryption_key, metadataIV) # Decrypt the data. decryptor = cipher.decryptor() encrypted_properties_list = decryptor.update(encrypted_properties_list) + decryptor.finalize() # Unpad the data. unpadder = PKCS7(128).unpadder() encrypted_properties_list = unpadder.update(encrypted_properties_list) + unpadder.finalize() encrypted_properties_list = encrypted_properties_list.decode('utf-8') # Strip the square braces from the ends and split string into list. encrypted_properties_list = loads(encrypted_properties_list) entity_iv, encrypted_properties, content_encryption_key = \ (encryption_data.content_encryption_IV, encrypted_properties_list, content_encryption_key) decrypted_entity = deepcopy(entity) for property in encrypted_properties_list: value = entity[property] digest = Hash(SHA256(), default_backend()) digest.update(entity_iv + (entity['RowKey'] + entity['PartitionKey'] + property).encode('utf-8')) propertyIV = digest.finalize() propertyIV = propertyIV[:16] cipher = _generate_AES_CBC_cipher(content_encryption_key, propertyIV) # Decrypt the property. decryptor = cipher.decryptor() decrypted_data = (decryptor.update(value.value) + decryptor.finalize()) # Unpad the data. unpadder = PKCS7(128).unpadder() decrypted_data = (unpadder.update(decrypted_data) + unpadder.finalize()) decrypted_data = decrypted_data.decode('utf-8') decrypted_entity[property] = decrypted_data decrypted_entity.pop('_ClientEncryptionMetadata1') decrypted_entity.pop('_ClientEncryptionMetadata2') # Assert self.assertEqual(decrypted_entity['sex'], 'male')
def test_validate_encryption(self): # Arrange entity = self._create_default_entity_for_encryption() key_encryption_key = KeyWrapper('key1') self.ts.key_encryption_key = key_encryption_key self.ts.insert_entity(self.table_name, entity) # Act self.ts.key_encryption_key = None entity = self.ts.get_entity(self.table_name, entity['PartitionKey'], entity['RowKey']) # Note the minor discrepancy from the normal decryption process: because the entity was retrieved # without being decrypted, the encrypted_properties list is now stored in an EntityProperty object # and is already raw bytes. encrypted_properties_list = entity['_ClientEncryptionMetadata2'].value encryption_data = entity['_ClientEncryptionMetadata1'] encryption_data = _dict_to_encryption_data(loads(encryption_data)) content_encryption_key = key_encryption_key.unwrap_key( encryption_data.wrapped_content_key.encrypted_key, encryption_data.wrapped_content_key.algorithm) digest = Hash(SHA256(), default_backend()) digest.update(encryption_data.content_encryption_IV + (entity['RowKey'] + entity['PartitionKey'] + '_ClientEncryptionMetadata2').encode('utf-8')) metadataIV = digest.finalize() metadataIV = metadataIV[:16] cipher = _generate_AES_CBC_cipher(content_encryption_key, metadataIV) # Decrypt the data. decryptor = cipher.decryptor() encrypted_properties_list = decryptor.update( encrypted_properties_list) + decryptor.finalize() # Unpad the data. unpadder = PKCS7(128).unpadder() encrypted_properties_list = unpadder.update( encrypted_properties_list) + unpadder.finalize() encrypted_properties_list = encrypted_properties_list.decode('utf-8') # Strip the square braces from the ends and split string into list. encrypted_properties_list = loads(encrypted_properties_list) entity_iv, encrypted_properties, content_encryption_key = \ (encryption_data.content_encryption_IV, encrypted_properties_list, content_encryption_key) decrypted_entity = deepcopy(entity) for property in encrypted_properties_list: value = entity[property] digest = Hash(SHA256(), default_backend()) digest.update(entity_iv + (entity['RowKey'] + entity['PartitionKey'] + property).encode('utf-8')) propertyIV = digest.finalize() propertyIV = propertyIV[:16] cipher = _generate_AES_CBC_cipher(content_encryption_key, propertyIV) # Decrypt the property. decryptor = cipher.decryptor() decrypted_data = (decryptor.update(value.value) + decryptor.finalize()) # Unpad the data. unpadder = PKCS7(128).unpadder() decrypted_data = (unpadder.update(decrypted_data) + unpadder.finalize()) decrypted_data = decrypted_data.decode('utf-8') decrypted_entity[property] = decrypted_data decrypted_entity.pop('_ClientEncryptionMetadata1') decrypted_entity.pop('_ClientEncryptionMetadata2') # Assert self.assertEqual(decrypted_entity['sex'], 'male')