예제 #1
0
파일: AES.py 프로젝트: ech2901/pyaes
    def decrypt(self,
                ciphertext: bytes,
                password: bytes,
                size: int,
                salt: bytes = None,
                iv: bytes = None):
        """
        Processes arguments to an intermediate state, then passes to the _decrypt_ function.
        Processes output from the _decrypt_ function for use as output.

        :param ciphertext: bytes
        :param password: bytes
        :param size: int
        :param salt: bytes
        :param iv: bytes
        :return: bytes
        """

        # Convert plaintext to a list of blocks
        # Each block is 16 GF objects
        blocks = self.to_blocks(ciphertext)

        if salt is None:
            # If salt is not given via argument, generate a random one
            salt = urandom(self.salt_size)

        # Generate an iterable that loops over the key schedule repeatedly
        key = iter_key([
            GF(i) for i in phash(self.hash_algo, password, salt,
                                 self.hash_iters, size // 8)
        ],
                       size,
                       reverse=True)

        if iv is None:
            iv = [GF(i) for i in urandom(16)]
        elif len(iv) != 16:
            raise ValueError
        else:
            # convert iv to a list of GF objects
            iv = [GF(i) for i in iv]

        # select appropriate decryption key size
        # raise a ValueError if the given key size is invalid
        if size == 128:
            dec_func = decrypt_128
        elif size == 192:
            dec_func = decrypt_192
        elif size == 256:
            dec_func = decrypt_256
        else:
            raise ValueError

        # Actually perform the decryption
        blocks = self._decrypt_(blocks, key, iv, dec_func)
        # Process and return newly decrypted blocks to a usable format
        return self.from_blocks(blocks)
예제 #2
0
    def test_input_1(self):
        ciphertext = hex_to_arr(r'69c4e0d86a7b0430d8cdb78070b4c55a')
        key = hex_to_arr(r'000102030405060708090a0b0c0d0e0f')
        expected_out = hex_to_arr(r'00112233445566778899aabbccddeeff')

        test_out = Core.decrypt_128(ciphertext, iter_key(key, 128, reverse=True))

        for expected, test in zip(expected_out, test_out):
            self.assertEqual(expected, test)
예제 #3
0
    def test_input_1(self):
        ciphertext = hex_to_arr(r'8ea2b7ca516745bfeafc49904b496089')
        key = hex_to_arr(r'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f')
        expected_out = hex_to_arr(r'00112233445566778899aabbccddeeff')

        test_out = Core.decrypt_256(ciphertext, iter_key(key, 256, reverse=True))

        for expected, test in zip(expected_out, test_out):
            self.assertEqual(expected, test)
예제 #4
0
    def test_input_1(self):
        ciphertext = hex_to_arr(r'dda97ca4864cdfe06eaf70a0ec0d7191')
        key = hex_to_arr(r'000102030405060708090a0b0c0d0e0f1011121314151617')
        expected_out = hex_to_arr(r'00112233445566778899aabbccddeeff')

        test_out = Core.decrypt_192(ciphertext, iter_key(key, 192, reverse=True))

        for expected, test in zip(expected_out, test_out):
            self.assertEqual(expected, test)
예제 #5
0
파일: AES.py 프로젝트: ech2901/pyaes
    def encrypt(self,
                plaintext: bytes,
                password: bytes,
                size: int,
                salt: bytes = None,
                iv: bytes = None):
        """
        Processes arguments to an intermediate state, then passes to the _encrypt_ function.
        Processes output from the _encrypt_ function for use as output.

        :param plaintext: bytes
        :param password: bytes
        :param size: int
        :param salt: bytes
        :param iv: bytes
        :return: bytes
        """

        # Convert plaintext to a list of blocks
        # Each block is 16 GF objects
        blocks = self.to_blocks(plaintext)

        if salt is None:
            # If salt is not given via argument, generate a random one
            salt = urandom(self.salt_size)

        # Generate an iterable that loops over the key schedule repeatedly
        key = iter_key([
            GF(i) for i in phash(self.hash_algo, password, salt,
                                 self.hash_iters, size // 8)
        ], size)

        if iv is None:
            # If iv is not given via argument, generate a random one
            iv = [GF(i) for i in urandom(16)]
        elif len(iv) != 16:
            # If iv is given via argument, make sure it's usable
            raise ValueError
        else:
            # convert iv to a list of GF objects
            iv = [GF(i) for i in iv]

        # select appropriate encryption key size
        # raise a ValueError if the given key size is invalid
        if size == 128:
            enc_func = encrypt_128
        elif size == 192:
            enc_func = encrypt_192
        elif size == 256:
            enc_func = encrypt_256
        else:
            raise ValueError

        # Actually perform the encryption
        blocks, *outputs = self._encrypt_(blocks, key, iv, enc_func)

        # Process newly encrypted blocks to a usable format
        out = self.from_blocks(blocks)

        # If an IV is returned in the format of a list with GF elements
        # Convert it back to bytes without any stripping of trailing 0s
        if len(outputs):
            outputs = [self.from_blocks(outputs, False)]

        # Insert the salt into the outputs
        outputs.insert(0, salt)

        return (out, *outputs)
예제 #6
0
 def test_variable_plaintext(self):
     for expected_plaintext, key, ciphertext in self.tests['Variable Plaintext']:
         with self.subTest(expected_plaintext=expected_plaintext, key=key, ciphertext=ciphertext):
             test_plaintext = Core.decrypt_128(hex_to_arr(ciphertext), iter_key(hex_to_arr(key), 128, reverse=True))
             for e_item, t_item in zip(hex_to_arr(expected_plaintext), test_plaintext):
                 self.assertEqual(e_item, t_item)
예제 #7
0
 def test_variable_key(self):
     for plaintext, key, expected_ciphertext in self.tests['Variable Key']:
         with self.subTest(plaintext=plaintext, key=key, expected_ciphertext=expected_ciphertext):
             test_ciphertext = Core.encrypt_128(hex_to_arr(plaintext), iter_key(hex_to_arr(key), 128))
             for e_item, t_item in zip(hex_to_arr(expected_ciphertext), test_ciphertext):
                 self.assertEqual(e_item, t_item)