def test_parity(): key = key_1024 print("\nTest: parity") plaintext1 = bytes(b"Some plaintext ") + random_bytes(10) + bytes( b" anything can it be") plaintext2 = bytes(b"Some plaintext ") + random_bytes(10) + bytes( b" anything can it be2") ciphertext1 = h2b( subprocess.check_output([ "python", rsa_oracles_path, "encrypt", key.identifier, b2h(plaintext1) ]).strip().decode()) ciphertext2 = h2b( subprocess.check_output([ "python", rsa_oracles_path, "encrypt", key.identifier, b2h(plaintext2) ]).strip().decode()) key.texts.append({'cipher': b2i(ciphertext1)}) key.texts.append({'cipher': b2i(ciphertext2)}) msgs_recovered = parity(parity_oracle, key.publickey()) assert msgs_recovered[0] == b2i(plaintext1) assert msgs_recovered[1] == b2i(plaintext2) key.clear_texts()
def test_bit_flipping(): print("Test: cbc.bit_flipping(ciphertext=ciphertext[-2*AES.block_size:]," "plaintext=add_padding(plaintext)[-AES.block_size:],\nwanted_last_block=wanted, block_size=AES.block_size)") plaintext = bytes(b"money=10000&userdata=whateverdata%20huehuehue%20spam%20and%20eggs") wanted = add_padding(bytes(b'&admin=true')) ciphertext = h2b(subprocess.check_output(['python', cbc_oracles_path, 'encrypt', b2h(plaintext)]).strip().decode()) fake_cipher = cbc.bit_flipping(ciphertext=ciphertext[-2*AES.block_size:], plaintext=add_padding(plaintext)[-AES.block_size:], wanted=wanted, block_size=AES.block_size) fake_cipher = ciphertext[-AES.block_size*2:] + fake_cipher decrypted = h2b(subprocess.check_output(['python', cbc_oracles_path, 'decrypt', b2h(fake_cipher)]).strip().decode()) assert decrypted[-len("&admin=true"):] == bytes(b"&admin=true")
def test_bleichenbacher_pkcs15(): print("\nTest: Bleichenbacher's PKCS 1.5 Padding Oracle") keys = [key_64, key_256, key_1024] for key in keys: pkcs15_padding_oracle_calls = [0] # must be mutable incremental_blinding = False if key.size < 512: incremental_blinding = True if key.size > 512: plaintext = randint(2, key.n) >> 16 plaintext |= 0x0002 << (key.size - 16) else: plaintext = randint(2, key.n) ciphertext = h2b( subprocess.check_output([ "python", rsa_oracles_path, "encrypt", key.identifier, i2h(plaintext) ]).strip().decode()) msgs_recovered = bleichenbacher_pkcs15( pkcs15_padding_oracle, key.publickey(), ciphertext, incremental_blinding=incremental_blinding, oracle_key=key, pkcs15_padding_oracle_calls=pkcs15_padding_oracle_calls) log.info('For keysize {}: pkcs15_padding_oracle_calls = {}'.format( key.size, pkcs15_padding_oracle_calls[0])) assert msgs_recovered[0] == plaintext key.clear_texts()
def test_fake_ciphertext_decryption_oracle(amount=5): for _ in range(amount): new_plaintext = random_bytes(randint(1, 10)) new_plaintext_padded = add_padding(new_plaintext, block_size) print("Test small: cbc.fake_ciphertext(new_plaintext_padded, decryption_oracle=decryption_oracle)") new_ciphertext = cbc.fake_ciphertext(new_plaintext_padded, decryption_oracle=decryption_oracle) decrypted = h2b(subprocess.check_output( ['python', cbc_oracles_path, 'decrypt', b2h(new_ciphertext)]).strip().decode()) assert decrypted == new_plaintext for _ in range(amount): new_plaintext = random_bytes(randint(10, 50)) new_plaintext_padded = add_padding(new_plaintext, block_size) print("Test large: cbc.fake_ciphertext(new_plaintext_padded, decryption_oracle=decryption_oracle)") new_ciphertext = cbc.fake_ciphertext(new_plaintext_padded, decryption_oracle=decryption_oracle, padding_oracle=padding_oracle) decrypted = h2b(subprocess.check_output( ['python', cbc_oracles_path, 'decrypt', b2h(new_ciphertext)]).strip().decode()) assert decrypted == new_plaintext
def test_md4(): print("Test: md4") assert md4(bytes(b"")) == h2b("31d6cfe0d16ae931b73c59d7e0c089c0") assert md4(bytes(b"a")) == h2b("bde52cb31de33e46245e05fbdbd6fb24") assert md4(bytes(b"abc")) == h2b("a448017aaf21d8525fc10ae87aa6729d") assert md4( bytes(b"message digest")) == h2b("d9130a8164549fe818874806e1c7014b") assert md4(bytes(b"abcdefghijklmnopqrstuvwxyz")) == h2b( "d79e1c308aa5bbcdeea8ed63df412da9") assert md4( bytes(b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" )) == h2b("043f8582f241db351ce627e153e7f0e4") assert md4( bytes( b"12345678901234567890123456789012345678901234567890123456789012345678901234567890" )) == h2b("e33b4ddc9c38f2199c3e7b164fcc0536")
def test_manger(): keys = [key_64, key_256, key_1024, key_2048] for key in keys: manger_padding_oracle_calls = [0] plaintext = randint(2, key.n) >> 8 ciphertext = h2b( subprocess.check_output([ "python", rsa_oracles_path, "encrypt", key.identifier, i2h(plaintext) ]).strip().decode()) msgs_recovered = manger( oaep_padding_oracle, key.publickey(), ciphertext, oracle_key=key, manger_padding_oracle_calls=manger_padding_oracle_calls) log.success('For keysize {}: oaep_padding_oracle_calls = {}'.format( key.size, manger_padding_oracle_calls[0])) assert msgs_recovered[0] == plaintext key.clear_texts()
if plain[:2] == bytes(b'\x00\x01') and plain_hash == asn1 + hash_msg: return True return False if __name__ == '__main__': if len(sys.argv) < 4 or sys.argv[1] not in ['encrypt', 'decrypt', 'sign', 'verify', 'parity', 'verify_bleichenbacher_middle', 'verify_bleichenbacher_suffix']: print("Usage: {} encrypt|decrypt|sign|verify|parity|verify_bleichenbacher_suffix|verify_bleichenbacher_middle " \ "key hexdata [more hexdata]".format(sys.argv[0])) sys.exit(1) key = RSAKey.import_key(sys.argv[2]) if sys.argv[1] == 'encrypt': print(b2h(encrypt(h2b(sys.argv[3]), key))) elif sys.argv[1] == 'decrypt': print(b2h(decrypt(h2b(sys.argv[3]), key))) elif sys.argv[1] == 'sign': print(b2h(sign(h2b(sys.argv[3]), key))) elif sys.argv[1] == 'verify': print(verify(h2b(sys.argv[3]), h2b(sys.argv[4]), key)) elif sys.argv[1] == 'parity': print(parity_oracle(h2b(sys.argv[3]))) elif sys.argv[1] == 'verify_bleichenbacher_suffix': message = h2b(sys.argv[3])
payload = iv + payload try: decrypt(payload, iv_as_key) except BadPadding as e: return False return True blocks_with_correct_padding = encrypt(bytes(b'A' * (block_size + 5)))[block_size:] def decryption_oracle(payload): global iv_as_key iv = bytes(b'A' * block_size) payload = iv + payload + blocks_with_correct_padding plaintext = decrypt(payload, iv_as_key) if iv_as_key: return xor(plaintext[block_size:block_size * 2], iv) return xor(plaintext[:block_size], iv) if __name__ == '__main__': if len(sys.argv) != 3 or sys.argv[1] not in ['encrypt', 'decrypt']: print("Usage: {} encrypt|decrypt data".format(sys.argv[0])) sys.exit(1) if sys.argv[1] == 'encrypt': print(b2h(encrypt(h2b(sys.argv[2])))) else: print(b2h(decrypt(h2b(sys.argv[2]))))