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)
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)
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)
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)
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)
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)
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)
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)
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
def test_apply_none_bytes_raises_typeerror(self): with self.assertRaises(TypeError): PKCS7Padding.apply(None, 1)
def test_apply_blksize_over_bounds_raises(self): b = b'YELLOW SUBMARINE' with self.assertRaises(InvalidPaddingException): PKCS7Padding.apply(b, 256)
def test_apply_negative_blksize_raises(self): b = b'YELLOW SUBMARINE' with self.assertRaises(InvalidPaddingException): PKCS7Padding.apply(b, -1)