Пример #1
0
    def test_unapply_whole_block_padding(self):
        padded = b"YELLOW\x03\x03\x03"
        expected_bytes = b"YELLOW"

        actual_bytes = PKCS7Padding.unapply(padded)

        self.assertEqual(expected_bytes, actual_bytes)
Пример #2
0
    def test_unapply_cryptopals_case(self):
        padded = b"YELLOW SUBMARINE\x04\x04\x04\x04"
        expected_bytes = b"YELLOW SUBMARINE"

        actual_bytes = PKCS7Padding.unapply(padded)

        self.assertEqual(expected_bytes, actual_bytes)
Пример #3
0
    def test_apply_bytes_size_mutliple_of_blksize_adds_extra_block(self):
        b = b"YELLOW"
        expected_padded = b"YELLOW\x03\x03\x03"

        actual_padded = PKCS7Padding.apply(b, 3)

        self.assertEqual(expected_padded, actual_padded)
Пример #4
0
    def test_unapply_all_padding_returns_empty(self):
        padded = b"\x04\x04\x04\x04"
        expected_bytes = b""

        actual_bytes = PKCS7Padding.unapply(padded)

        self.assertEqual(expected_bytes, actual_bytes)
Пример #5
0
    def test_apply_empty_bytes_adds_padding(self):
        b = b''
        expected_padded = b"\x04\x04\x04\x04"

        actual_padded = PKCS7Padding.apply(b, 4)

        self.assertEqual(expected_padded, actual_padded)
Пример #6
0
    def test_apply_cryptopals_case(self):
        b = b"YELLOW SUBMARINE"
        expected_padded = b"YELLOW SUBMARINE\x04\x04\x04\x04"

        actual_padded = PKCS7Padding.apply(b, 20)

        self.assertEqual(expected_padded, actual_padded)
Пример #7
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)
Пример #8
0
    def encryption_oracle(b: bytes) -> bytes:
        """
        params:
            b: bytes to encrypt
        returns:
            `b` encrypted using AES-128-ECB
            appends `unknownstr` to `b` before encrypting
        """
        plain = PKCS7Padding.apply(b + unknownstr, blksize)
        cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
        ecb = ECBMode(blksize, cipher.encrypt, cipher.decrypt)

        return ecb.encrypt(plain)
Пример #9
0
def encrypt_profile(profile: str) -> bytes:
    """
    params:
        profile: encoded profile
    returns:
        `profile` encrypted using AES-128 ECB mode with a consistent key
    """
    blksize = 16
    plain = PKCS7Padding.apply(profile.encode(), blksize)
    cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
    ecb = ECBMode(blksize, cipher.encrypt, cipher.decrypt)

    return ecb.encrypt(plain)
Пример #10
0
def decrypt_profile(encrypted: bytes) -> str:
    """
    params:
        encrypted: profile encrypted using `encrypted_profile()`
    returns:
        encoded profile
    """
    cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
    ecb = ECBMode(16, cipher.encrypt, cipher.decrypt)

    padded = ecb.decrypt(encrypted)

    return PKCS7Padding.unapply(padded).decode()
Пример #11
0
def main():
    """
    Already implemented `PKCS7Padding.unapply()` in set2.challenge09
    Display that it solves the challenge
    """
    b = b"ICE ICE BABY\x04\x04\x04\x04"
    print("PKCS7Padding.unapply(%s):" % b)
    print(PKCS7Padding.unapply(b))

    b = b"ICE ICE BABY\x05\x05\x05\x05"
    print("PKCS7Padding.unapply(%s):" % b)
    try:
        PKCS7Padding.unapply(b)
    except (InvalidPaddingException):
        print("Exception raised")

    b = b"ICE ICE BABY\x01\x02\x03\x04"
    print("PKCS7Padding.unapply(%s):" % b)
    try:
        PKCS7Padding.unapply(b)
    except (InvalidPaddingException):
        print("Exception raised")
Пример #12
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
Пример #13
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
Пример #14
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)
Пример #15
0
def break_cbc(encrypted: bytes, iv: bytes, padding_oracle: Callable[[bytes, bytes], bool]) \
        -> bytes:
    """
    params:
        encrypted: encrypted message from `encryption_oracle()`
        iv: IV used for encryption from `encryption_oracle()`
        padding_oracle: `valid_padding()`
    returns:
        decrypted bytes for `encrypted`
    """
    decrypted = b''

    prev_blk = iv
    for curr_blk in blocks(encrypted, 16):
        decrypted += break_cbc_single_blk(prev_blk, curr_blk, padding_oracle)
        prev_blk = curr_blk

    return PKCS7Padding.unapply(decrypted)
Пример #16
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)
Пример #17
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
Пример #18
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
Пример #19
0
    def test_unapply_padding_value_larger_than_valid_raises(self):
        padded = b"YELLOW\x16\x16\x16"

        with self.assertRaises(InvalidPaddingException):
            PKCS7Padding.unapply(padded)
Пример #20
0
    def test_unapply_padding_ending_with_zero_raises(self):
        padded = b"YELLOW\x00"

        with self.assertRaises(InvalidPaddingException):
            PKCS7Padding.unapply(padded)
Пример #21
0
    def test_apply_negative_blksize_raises(self):
        b = b'YELLOW SUBMARINE'

        with self.assertRaises(InvalidPaddingException):
            PKCS7Padding.apply(b, -1)
Пример #22
0
    def test_apply_blksize_over_bounds_raises(self):
        b = b'YELLOW SUBMARINE'

        with self.assertRaises(InvalidPaddingException):
            PKCS7Padding.apply(b, 256)
Пример #23
0
 def test_apply_none_bytes_raises_typeerror(self):
     with self.assertRaises(TypeError):
         PKCS7Padding.apply(None, 1)
Пример #24
0
    def test_unapply_padding_value_incosistent(self):
        padded = b"ICE ICE BABY\x01\x02\x03\x04"

        with self.assertRaises(InvalidPaddingException):
            PKCS7Padding.unapply(padded)
Пример #25
0
    def test_unapply_padding_value_does_not_match_number_of_pads(self):
        padded = b"ICE ICE BABY\x05\x05\x05\x05"

        with self.assertRaises(InvalidPaddingException):
            PKCS7Padding.unapply(padded)