def test_set_password_existing(self): self.dynamodb.get_item.return_value = { 'Item': (EncryptedPayload('a', 'b', 'c', ORBIT_REGION, 'utf-8').dynamodb_item()) } was_set = self.password.set_password(self.app_region, PASSWORD_NAME, lambda: PASSWORD) self.assertFalse(was_set) self.dynamodb.put_item.assert_not_called()
def encrypt(self, app_region, plaintext, create_key=True): """ Encrypt data for an application. :param app_region: SpaceAppRegion. :param plaintext: Plaintext blob. :param create_key: Create key if missing (else fail). :return: EncryptedPayload. """ region = app_region.region # Get DEK: logger.debug('Fetching fresh data key...') try: alias_name = self._kms_key.get_key_alias(app_region) kms = self._clients.kms(region) data_key = kms.generate_data_key(KeyId=alias_name, KeySpec='AES_256') except ClientError as e: e_message = e.response['Error'].get('Message', '') if create_key and 'is not found' in e_message: # Key not found, create and try again: self._kms_key.create_key(app_region) return self.encrypt(app_region, plaintext) raise e # Encode and pad data: encoding = 'bytes' if isinstance(plaintext, six.string_types): encoding = 'utf-8' if six.PY3: # pragma: no cover plaintext = bytes(plaintext, encoding) else: # pragma: no cover plaintext = plaintext.encode(encoding) pad_length = BLOCK_SIZE - (len(plaintext) % BLOCK_SIZE) padded = plaintext + (pad_length * bchr(pad_length)) logger.debug('Padded %s %s to %s.', len(plaintext), encoding, len(padded)) logger.debug('Encrypting data with data key...') iv = self._random.read(BLOCK_SIZE) cipher = AES.new(data_key['Plaintext'], CIPHER_MODE, iv) ciphertext = cipher.encrypt(padded) encrypted_key = data_key['CiphertextBlob'] return EncryptedPayload(iv, ciphertext, encrypted_key, region, encoding)
def test_get_password_existing(self): self.dynamodb.get_item.return_value = { 'Item': (EncryptedPayload('a', 'b', 'c', ORBIT_REGION, 'utf-8').dynamodb_item()) } encrypted, decrypt_func = self.password.get_password( self.app_region, PASSWORD_NAME) self.assertIsInstance(encrypted, EncryptedPayload) self.assertEquals(encrypted.iv, 'a') self.dynamodb.put_item.assert_not_called() self.kms_crypto.encrypt.assert_not_called() # Decrypt is deferred until absolutely necessary: self.kms_crypto.decrypt_payload.assert_not_called() decrypt_func() self.kms_crypto.decrypt_payload.assert_called_with(ANY)
import unittest from spacel.security.payload import EncryptedPayload from test import ORBIT_REGION IV = b'0000000000000000' CIPHERTEXT = b'0000000000000000' KEY = b'0000000000000000' ENCODING = 'utf-8' ENCRYPTED_PAYLOAD = EncryptedPayload(IV, CIPHERTEXT, KEY, ORBIT_REGION, ENCODING) class TestEncryptedPayload(unittest.TestCase): def setUp(self): self.payload = ENCRYPTED_PAYLOAD def test_round_trip_dynamodb(self): dynamodb_item = self.payload.dynamodb_item() payload = EncryptedPayload.from_dynamodb_item(dynamodb_item) self.assertEquals(IV, payload.iv) self.assertEquals(CIPHERTEXT, payload.ciphertext) self.assertEquals(KEY, payload.key) self.assertEquals(ORBIT_REGION, payload.key_region) self.assertEquals(ENCODING, payload.encoding) def test_round_trip_json(self): as_json = self.payload.json() payload = EncryptedPayload.from_json(as_json) self.assertEquals(IV, payload.iv) self.assertEquals(CIPHERTEXT, payload.ciphertext)
from spacel.security.payload import EncryptedPayload IV = b'0000000000000000' CIPHERTEXT = b'0000000000000000' KEY = b'0000000000000000' ENCODING = 'utf-8' REGION = 'us-east-1' PAYLOAD = EncryptedPayload(IV, CIPHERTEXT, KEY, REGION, ENCODING)