def test_aes_encrypt(self, mock_func):
        aes = AESCrypto()

        for item in AES_CBC_TEST_VECTORS:
            key = item['key'].decode('hex')
            iv = item['iv'].decode('hex')
            plain_text = item['plaintext'].decode('hex')
            expected_cipher_text = item['ciphertext'].decode('hex')

            mock_func.return_value = iv

            encrypted_with_iv_and_pad = aes.encrypt(key=key, data=plain_text)

            # Remove IV
            encrypted = encrypted_with_iv_and_pad[len(iv):]

            # Unpad
            encrypted = encrypted[:-len(plain_text)]

            self.assertEqual(encrypted, expected_cipher_text)

            # Also test round-trip
            decrypted = aes.decrypt(key=key, data=encrypted_with_iv_and_pad)
            self.assertEqual(decrypted, plain_text)
Ejemplo n.º 2
0
    def test_aes_encrypt(self, mock_func):
        aes = AESCrypto()

        for item in AES_CBC_TEST_VECTORS:
            key = item['key'].decode('hex')
            iv = item['iv'].decode('hex')
            plain_text = item['plaintext'].decode('hex')
            expected_cipher_text = item['ciphertext'].decode('hex')

            mock_func.return_value = iv

            encrypted_with_iv_and_pad = aes.encrypt(key=key, data=plain_text)

            # Remove IV
            encrypted = encrypted_with_iv_and_pad[len(iv):]

            # Unpad
            encrypted = encrypted[:-len(plain_text)]

            self.assertEqual(encrypted, expected_cipher_text)

            # Also test round-trip
            decrypted = aes.decrypt(key=key, data=encrypted_with_iv_and_pad)
            self.assertEqual(decrypted, plain_text)
Ejemplo n.º 3
0
class HybridCryptoEncrypter(HybridCryptoMixin):
    """
    Class which provides functionality for encrypting data using hybrid
    cryptosystem.
    """
    def __init__(self, keys_path):
        """
        :param keys_path: Path to the directory containg public keys.
        :type keys_path: ``str``
        """
        if not os.path.exists(keys_path):
            raise ValueError('Directory with public keys doesnt exist')

        self._keys_path = keys_path

        self._keyczar = Encrypter.Read(self._keys_path)
        self._aes = AESCrypto()

    def encrypt(self, data):
        """
        Encrypt provided data.
        """
        if len(data) > self.long_message_threshold:
            cipher_text = self._encrypt_long_message(data=data)
        else:
            cipher_text = self._encrypt_short_message(data=data)

        return cipher_text

    def _encrypt_short_message(self, data):
        """
        Encrypt a short message using public-key cryptography.

        :param data: Data to encrypt.
        :type data: ``str``
        """
        header = 'hpkc'
        data = str(data)

        if len(data) > self.long_message_threshold:
            raise ValueError('Data is too long and cant be encrypted using '
                             'PKC')

        cipher_text = header + self._keyczar.Encrypt(data)
        return cipher_text

    def _encrypt_long_message(self, data):
        """
        Encrypt a long message using hybrid cryptography.

        Data is encrypted using the following approach:

        1. Generate fresh symmetric AES key for the data encapsulation scheme
        2. Encrypt provided data using data encapsulation scheme
        3. Encrypt generates AES key using key encapsulation scheme (PKC)
        4. Assemble a final message - header + pkc_encrypted_aes_key +
        delimiter + aes_encrypted_data

        :param data: Data to encrypt.
        :type data: ``str``
        """
        header = 'haes'

        # Generate a fresh symmetric key for the data encapsulation scheme
        aes_key = RandBytes(n=self.aes_key_size)
        aes_key = str(aes_key)

        # Encrypt message using data encapsulation scheme (AES)
        aes_cipher_text = self._aes.encrypt(key=aes_key, data=data)
        aes_cipher_text = Base64WSEncode(aes_cipher_text)

        # Encrypt AES key using key encapsulation scheme
        key_cipher_text = self._keyczar.Encrypt(aes_key)

        # Assemble a final message
        parts = [header, key_cipher_text, self.delimiter, aes_cipher_text]
        msg_cipher_text = ''.join(parts)

        return msg_cipher_text

    def _aes_encrypt(self, key, data):
        header = 'paes'
        cipher_text = self._aes.encrypt(key=key, data=data)

        msg_cipher_text = header + cipher_text
        return msg_cipher_text
Ejemplo n.º 4
0
class HybridCryptoEncrypter(HybridCryptoMixin):
    """
    Class which provides functionality for encrypting data using hybrid
    cryptosystem.
    """

    def __init__(self, keys_path):
        """
        :param keys_path: Path to the directory containg public keys.
        :type keys_path: ``str``
        """
        if not os.path.exists(keys_path):
            raise ValueError('Directory with public keys doesnt exist')

        self._keys_path = keys_path

        self._keyczar = Encrypter.Read(self._keys_path)
        self._aes = AESCrypto()

    def encrypt(self, data):
        """
        Encrypt provided data.
        """
        if len(data) > self.long_message_threshold:
            cipher_text = self._encrypt_long_message(data=data)
        else:
            cipher_text = self._encrypt_short_message(data=data)

        return cipher_text

    def _encrypt_short_message(self, data):
        """
        Encrypt a short message using public-key cryptography.

        :param data: Data to encrypt.
        :type data: ``str``
        """
        header = 'hpkc'
        data = str(data)

        if len(data) > self.long_message_threshold:
            raise ValueError('Data is too long and cant be encrypted using '
                             'PKC')

        cipher_text = header + self._keyczar.Encrypt(data)
        return cipher_text

    def _encrypt_long_message(self, data):
        """
        Encrypt a long message using hybrid cryptography.

        Data is encrypted using the following approach:

        1. Generate fresh symmetric AES key for the data encapsulation scheme
        2. Encrypt provided data using data encapsulation scheme
        3. Encrypt generates AES key using key encapsulation scheme (PKC)
        4. Assemble a final message - header + pkc_encrypted_aes_key +
        delimiter + aes_encrypted_data

        :param data: Data to encrypt.
        :type data: ``str``
        """
        header = 'haes'

        # Generate a fresh symmetric key for the data encapsulation scheme
        aes_key = RandBytes(n=self.aes_key_size)
        aes_key = str(aes_key)

        # Encrypt message using data encapsulation scheme (AES)
        aes_cipher_text = self._aes.encrypt(key=aes_key, data=data)
        aes_cipher_text = Base64WSEncode(aes_cipher_text)

        # Encrypt AES key using key encapsulation scheme
        key_cipher_text = self._keyczar.Encrypt(aes_key)

        # Assemble a final message
        parts = [header, key_cipher_text, self.delimiter, aes_cipher_text]
        msg_cipher_text = ''.join(parts)

        return msg_cipher_text

    def _aes_encrypt(self, key, data):
        header = 'paes'
        cipher_text = self._aes.encrypt(key=key, data=data)

        msg_cipher_text = header + cipher_text
        return msg_cipher_text