def test_ch27(self): key = generate_random_key(16) enc_oracle = partial(encryption_oracle, key=key, blocksize=16) dec_oracle = partial(decryption_oracle, key=key, blocksize=16) recovered_key = break_cbc_oracle(enc_oracle, dec_oracle) self.assertEquals(recovered_key, key)
def break_ctr_api(plaintext, ctr_key=None): ''' Imagine the "edit" function was exposed to attackers by means of an API call that didn't reveal the key or the original plaintext; the attacker has the ciphertext and controls the offset and "new text". Recover the original plaintext. ciphera = a_plaintext xor keystream cipherb = b_plaintext xor keystream ciphera xor cipherb = a_plaintext xor keystream xor b_plaintext xor keystream ciphera xor cipherb xor b_plaintext = a_plaintext ''' if ctr_key is None: ctr_key = generate_random_key() ciphertext = aes_ctr(plaintext, ctr_key) def api(offset, newtext): return edit_ctr_cipher(ciphertext, ctr_key, offset, newtext) a_cipher = ciphertext b_plaintext = b'A' * len(ciphertext) b_cipher = api(0, b_plaintext) return bytes( [a ^ b ^ c for a, b, c in zip(a_cipher, b_cipher, b_plaintext)])
def test_ch17(self): key = generate_random_key() oracle = encryption_get_oracle_func(key, cbc_padding_oracle) lst = [ "MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=", "MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=", "MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==", "MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==", "MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl", "MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==", "MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==", "MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=", "MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=", "MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93" ] for plaintext in lst: #test funcs ciphertext = produce_ciphertext(plaintext, key) self.assertTrue(oracle(ciphertext)) self.assertEqual( unpadpkcs7(break_cbc_padding_oracle(oracle, ciphertext)), plaintext)
def test_ch16(self): key = generate_random_key() dec_oracle = encryption_get_oracle_func(key, decryption_oracle16) enc_oracle = encryption_get_oracle_func(key, encryption_oracle16) self.assertIn("admin=true", break_cbc_oracle(enc_oracle, dec_oracle))
def test_ch13(self): key = generate_random_key() dec_oracle = encryption_get_oracle_func(key, decryption_oracle13) enc_oracle = encryption_get_oracle_func(key, encryption_oracle13) obj = cut_and_paste_attack("*****@*****.**", enc_oracle, dec_oracle) self.assertEqual("admin", obj["role"])
def test_ch26(self): key = generate_random_key() dec_oracle = partial(aes_ctr_encrypt_decrypt, key=key, nonce=form_nonce(0)) enc_oracle = partial(aes_ctr_encryption_oracle, key=key, blocksize=16) self.assertIn("admin=true", aes_ctr_break_bitflipping(enc_oracle, dec_oracle))
def test_ch20(self): plaintexts = [] ciphertexts = [] key = generate_random_key(16) with open('static/19.txt', 'r') as myfile: for line in myfile.read().splitlines(): plaintexts.append(b64decode(line)) for plaintext in plaintexts: nonce = form_nonce(0) ciphertexts.append(aes_ctr_encrypt_decrypt(plaintext, key, nonce)) raise NotImplementedError
def test_ch12(self): cleartext = b64decode( "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg\ aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq\ dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg\ YnkK") key = generate_random_key() oracle = encryption_get_oracle_func(key, encryption_oracle2) mode = check_block_mode_decoupled(oracle) self.assertEqual(mode, AES_ECB_MODE) block_size = guess_block_size(oracle) self.assertEqual(16, block_size) self.assertEqual(break_ecb_oracle(oracle, block_size), cleartext)
def test_ch19(self): # this is a many time pad problem plaintexts = [] ciphertexts = [] key = generate_random_key(16) with open('static/19.txt', 'r') as myfile: for line in myfile.read().splitlines(): plaintexts.append(b64decode(line)) for plaintext in plaintexts: nonce = form_nonce(0) ciphertexts.append(aes_ctr_encrypt_decrypt(plaintext, key, nonce)) break_ctr_reused_nonce_substitutions(ciphertexts) raise NotImplementedError
def test_ch25(self): key = generate_random_key(16) with open('static/25.txt', 'r') as myfile: cipher = b64decode(myfile.read()) plaintext = unpadpkcs7(aes_ecb_decrypt(cipher, "YELLOW SUBMARINE")) nonce = form_nonce(0) ciphertext = aes_ctr_encrypt_decrypt(plaintext, key, nonce) edit_func = partial(edit_ciphertext, key=key) # test edit_ciphertext function result = edit_ciphertext(ciphertext, key, 32, "YELLOW") self.assertEquals( result, aes_ctr_encrypt_decrypt(plaintext[:32] + "YELLOW" + plaintext[38:], key, nonce)) # break it self.assertEquals(break_edit_ciphertext(ciphertext, edit_func), plaintext)
def test_ch14(self): cleartext = b64decode( "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg\ aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq\ dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg\ YnkK") key = generate_random_key() block_size = len(key) randomdata = Random.new().read(random.choice(range(1, 31))) oracle = partial(encryption_get_oracle_func(key, encryption_oracle14), randomdata=randomdata) self.assertEqual(len(randomdata), get_random_data_length(oracle)) filling_text = (block_size - (len(randomdata) % block_size)) * "A" out = break_ecb_oracle(oracle, block_size, filling_text, startindex=len(filling_text) + len(randomdata)) self.assertEqual(out, cleartext)
'''set3 solutions for cryptopals''' import secrets import random import time from Crypto.Cipher import AES from set1 import bin_to_hex, hex_to_bin, hex_to_base64, base64_to_bin, encrypt_repeating_xor, aes_ecb_decrypt, fixed_xor, english_score from set2 import pkcs7, validate_pkcs7, blockify, aes_cbc_encrypt, aes_cbc_decrypt, aes_ecb_encrypt, generate_random_key, unpad GLOBAL_RANDOM_KEY = generate_random_key() challenge_17_strings = [ b"MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=", b"MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=", b"MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==", b"MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==", b"MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl", b"MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==", b"MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==", b"MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=", b"MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=", b"MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93" ] def serve_cookie(iv=None): ''' This function approximates AES-CBC encryption on a webserver. It serves up a "new" cookie to the user so when they make a request on the server the server can figure out who is talking to it. ''' string_to_encode = challenge_17_strings[random.randint(0, len(challenge_17_strings) - 1)] return aes_cbc_encrypt(string_to_encode, GLOBAL_RANDOM_KEY, iv=iv), iv def consume_cookie(cipher, iv=None):
''' if ctr_key is None: ctr_key = generate_random_key() ciphertext = aes_ctr(plaintext, ctr_key) def api(offset, newtext): return edit_ctr_cipher(ciphertext, ctr_key, offset, newtext) a_cipher = ciphertext b_plaintext = b'A' * len(ciphertext) b_cipher = api(0, b_plaintext) return bytes( [a ^ b ^ c for a, b, c in zip(a_cipher, b_cipher, b_plaintext)]) challenge_26_aes_key = generate_random_key() def challenge_26_encrypt(string_in): to_return = 'comment1=cooking%20MCs;userdata=' + string_in.replace( '=', '%3d').replace( ';', '%3b') + ';comment2=%20like%20a%20pound%20of%20bacon' to_return = str.encode(to_return) return aes_ctr(to_return, challenge_26_aes_key) def challenge_26_detect_admin(cipher): decrypted = aes_ctr(cipher, challenge_26_aes_key) return decrypted.count(b";admin=true") > 0
def test_ch11(self): key = generate_random_key() oracle = encryption_get_oracle_func(key, encryption_oracle1) for _ in range(20): result, correct_result = check_block_mode(oracle) self.assertEqual(result, correct_result)