示例#1
0
    def encryption_oracle(b: bytes) -> bytes:
        """
        params:
            b: bytes to encrypt
        returns:
            `b` encrypted using AES-128 with a random key using either
            ECB mode or CBC mode randomly (one in two chance)
            also prepends 5-10 random bytes and appends 5-10 random bytes to
            `b` before encryption
            if CBC mode is used random bytes are used for the IV
        """
        prefix_size = random.randint(5, 10)
        prefix = rand_bytes_gen(prefix_size)
        suffix_size = random.randint(5, 10)
        suffix = rand_bytes_gen(suffix_size)

        plain = PKCS7Padding.apply(prefix+b+suffix, blksize)
        key = rand_bytes_gen(blksize)
        cipher = AES.new(key, AES.MODE_ECB)

        if use_ecb:
            # print("ECB")  # for manual verification
            ecb = ECBMode(blksize, cipher.encrypt, cipher.decrypt)
            return ecb.encrypt(plain)

        iv = rand_bytes_gen(blksize)
        cbc = CBCMode(
            blksize=blksize,
            encrypt_blk=cipher.encrypt,
            decrypt_blk=cipher.decrypt,
            iv=iv
        )

        # print("CBC")
        return cbc.encrypt(plain)
示例#2
0
    def test_decrypt_bytes_not_padded_raises(self):
        b = b"\x00\x01\x00\x01\x23"
        iv = b"\x03\x03"
        cbc = CBCMode(
            blksize=2,
            encrypt_blk=self.mock_fun,
            decrypt_blk=self.mock_fun,
            iv=iv,
        )

        with self.assertRaises(ValueError):
            cbc.decrypt(b)
示例#3
0
    def test_encrypt_bytes_of_proper_length(self):
        b = b"\x00\x01\x00\x01"
        iv = b"\x03\x03"
        expected_bytes = b"\x03\x03\x03\x03"

        cbc = CBCMode(
            blksize=2,
            encrypt_blk=self.mock_fun,
            decrypt_blk=self.mock_fun,
            iv=iv,
        )
        actual_bytes = cbc.encrypt(b)

        self.assertEqual(expected_bytes, actual_bytes)
示例#4
0
    def test_break_cbc_single_blk_nominal_case(self):
        plain = b"YELLOW SUBMARINE"
        iv = b"abcdefghijklmnop"

        cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
        cbc = CBCMode(
            blksize=16,
            encrypt_blk=cipher.encrypt,
            decrypt_blk=cipher.decrypt,
            iv=iv
        )
        encrypted = cbc.encrypt(plain)

        decrypted = break_cbc_single_blk(iv, encrypted, valid_padding)

        self.assertEqual(plain, decrypted)
示例#5
0
def is_admin(encrypted: bytes, blksize: int = 16) -> bool:
    """
    params:
        encrypted: message encrypted using `encryption_oracle()`
        blksize: blocksize used by `encryption_oracle()`
    returns:
        True if decrypted message contains ";admin=true;", False otherwise
    """
    cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
    cbc = CBCMode(blksize=blksize,
                  encrypt_blk=cipher.encrypt,
                  decrypt_blk=cipher.decrypt,
                  iv=CONSISTENT_IV)
    padded = cbc.decrypt(encrypted)
    decrypted = PKCS7Padding.unapply(padded)

    return b";admin=true;" in decrypted
示例#6
0
    def aes_cbc(plaintext: bytes) -> bytes:
        """
        params:
            b: bytes to encrypt
        returns:
            `b` encrypted using AES-128-CBC
            uses key as IV
        """
        padded = PKCS7Padding.apply(plaintext, blksize)
        cipher = AES.new(key, AES.MODE_ECB)
        cbc = CBCMode(
            blksize=blksize,
            encrypt_blk=cipher.encrypt,
            decrypt_blk=cipher.decrypt,
            iv=key,
        )

        return cbc.encrypt(padded)
示例#7
0
    def test_encrypt_decrypt_integration_case(self):
        key = b"YELLOW SUBMARINE"
        iv = b"THIS IS 16 BYTES"
        cipher = AES.new(key, AES.MODE_ECB)
        cbc = CBCMode(
            blksize=16,
            encrypt_blk=cipher.encrypt,
            decrypt_blk=cipher.decrypt,
            iv=iv,
        )
        plaintext = (b"Lorem ipsum dolo"
                     b"r sit amet, cons"
                     b"ectetur adipisci"
                     b"ng elitAAAAAAAAA")

        encrypted = cbc.encrypt(plaintext)
        decrypted = cbc.decrypt(encrypted)

        self.assertEqual(plaintext, decrypted)
示例#8
0
    def test_init_iv_smaller_than_blksize_returns_empty_bytes(self):
        iv = b"\x03"

        with self.assertRaises(ValueError):
            CBCMode(
                blksize=2,
                encrypt_blk=self.mock_fun,
                decrypt_blk=self.mock_fun,
                iv=iv,
            )
示例#9
0
    def test_init_iv_bigger_than_blksize_raises(self):
        iv = b"\x03\x03\x23"

        with self.assertRaises(ValueError):
            CBCMode(
                blksize=2,
                encrypt_blk=self.mock_fun,
                decrypt_blk=self.mock_fun,
                iv=iv,
            )
示例#10
0
    def validate_ascii(encrypted: bytes) -> bytes:
        """
        params:
            encrypted: message encrypted using `aes_cbc()`
        returns:
            decrypted bytes if they contain extended ascii characters,
            None otherwise
        """
        cipher = AES.new(key, AES.MODE_ECB)
        cbc = CBCMode(blksize=blksize,
                      encrypt_blk=cipher.encrypt,
                      decrypt_blk=cipher.decrypt,
                      iv=key)
        padded = cbc.decrypt(encrypted)
        decrypted = PKCS7Padding.unapply(padded)

        for c in decrypted:
            if c >= 128:
                return decrypted
        return None
示例#11
0
    def encryption_oracle(b: bytes) -> bytes:
        """
        params:
            b: bytes to encrypt
        returns:
            `b` encrypted using AES-128-CBC
            prepends `prefix` and appends `suffix` before encrypting
        """
        cleaned_data = b.replace(b';', b"';'").replace(b'=', b"'='")

        plain = PKCS7Padding.apply(prefix + cleaned_data + suffix, blksize)
        cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
        cbc = CBCMode(
            blksize=blksize,
            encrypt_blk=cipher.encrypt,
            decrypt_blk=cipher.decrypt,
            iv=CONSISTENT_IV,
        )

        return cbc.encrypt(plain)
示例#12
0
def encryption_oracle() -> Tuple[bytes, bytes]:
    """
    params:
        none
    returns:
        ciphertext: one of ten plaintexts encrypted using AES-128-CBC with `iv`
        iv: iv used to encrypt the ciphertext
    """
    plain_strs = (
        b"MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=",
        b"MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIH" +
        b"B1bXBpbic=",
        b"MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw" +
        b"==",
        b"MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==",
        b"MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl",
        b"MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==",
        b"MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==",
        b"MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=",
        b"MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=",
        b"MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93",
    )

    blksize = len(CONSISTENT_KEY)

    plain = base64.b64decode(plain_strs[random.randint(0,
                                                       len(plain_strs) - 1)])
    padded = PKCS7Padding.apply(plain, blksize)

    cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
    iv = rand_bytes_gen(blksize)
    cbc = CBCMode(blksize=blksize,
                  encrypt_blk=cipher.encrypt,
                  decrypt_blk=cipher.decrypt,
                  iv=iv)

    encrypted = cbc.encrypt(padded)

    return encrypted, iv
示例#13
0
def valid_padding(encrypted: bytes, iv: bytes) -> bool:
    """
    params:
        encrypted: encrypted message
        iv: IV used to encrypt `encrypted`
    returns:
        True if decryption of `encrypted` has valid padding
        False otherwise
    """
    blksize = len(CONSISTENT_KEY)

    cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
    cbc = CBCMode(blksize=blksize,
                  encrypt_blk=cipher.encrypt,
                  decrypt_blk=cipher.decrypt,
                  iv=iv)
    decrypted = cbc.decrypt(encrypted)

    try:
        PKCS7Padding.unapply(decrypted)
        return True
    except InvalidPaddingException:
        return False
示例#14
0
def main():
    """
    decrypt contents of a file encrypted using AES-128 in CBC mode
    """
    key = b"YELLOW SUBMARINE"
    iv = bytes(16)
    cipher = AES.new(key, AES.MODE_ECB)
    cbc = CBCMode(
        blksize=16,
        encrypt_blk=cipher.encrypt,
        decrypt_blk=cipher.decrypt,
        iv=iv
    )

    input_filename = os.path.join(pathlib.Path(__file__).parent, "input")
    with open(input_filename, 'r') as input_file:
        base64_str = input_file.read()
    base64_bytes = base64_str.replace('\n', '').encode("utf-8")
    encrypted = base64.decodebytes(base64_bytes)

    message = cbc.decrypt(encrypted)

    print(message.decode("utf-8", errors="ignore"))