def encrypt_profile(email: str) -> bytes: global key if key is None: key = generate_bytes() data = profile_for(email) data = pkcs7_pad(bytes(data, "ascii")) return encrypt_aes_128_ecb(data, key)
def encrypt_random_string(bs: int = 16, teststring: str = None) -> bytes: iv = generate_bytes() # noinspection PyTypeChecker strings: List[Base64] = ["MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=", "MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=", "MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==", "MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==", "MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl", "MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==", "MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==", "MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=", "MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=", "MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93"] rand_string = from_base64(choice(strings)) if teststring: rand_string = teststring return iv + encrypt_cbc(rand_string, fixkey, iv, bs)
from typing import Callable from ch01 import from_base64, Base64 from ch07 import encrypt_aes_128_ecb from ch09 import pkcs7_pad from ch10 import strip_padding from ch11 import generate_bytes, ecb_or_cbc unknown_string = from_base64(Base64("""Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg YnkK""")) key = generate_bytes() def encryption_oracle_ecb(data: bytes) -> bytes: global key data = pkcs7_pad(data + unknown_string) return encrypt_aes_128_ecb(data, key) # needs a rewrite def find_block_size(func: Callable[[bytes], bytes]): return len(func(b"A")) def crack_ecb_simple(func: Callable[[bytes], bytes], left_base_size: int = 0) -> bytes: # block_size = find_block_size(func) # wrong block_size = 16 answer = [] base_byte = b"A"
from collections import defaultdict from ch10 import decrypt_cbc, encrypt_cbc from ch11 import generate_bytes iv: bytes = generate_bytes() key: bytes = generate_bytes() def encrypt_cbc_fix(data: bytes) -> bytes: global key global iv return encrypt_cbc(data, key, iv) def decrypt_cbc_fix(data: bytes, padding: bool = True) -> bytes: global key global iv return decrypt_cbc(data, key, iv, 16, padding) def encrypt_wrapper(data: bytes) -> bytes: left = b"comment1=cooking%20MCs;userdata=" right = b";comment2=%20like%20a%20pound%20of%20bacon" data = data.replace(b';', b'%3B').replace(b'=', b'%3D') data = left + data + right return encrypt_cbc_fix(data) def check_admin(data: bytes) -> bool: dec: bytes = decrypt_cbc_fix(data)
from random import randint from typing import Callable from ch11 import generate_bytes from ch12 import crack_ecb_simple, encryption_oracle_ecb random_bytes = generate_bytes(randint(0, 64)) def encryption_oracle_ecb_hard(data: bytes) -> bytes: global random_bytes data = random_bytes + data return encryption_oracle_ecb(data) def crack_ecb_hard(func: Callable[[bytes], bytes]) -> bytes: # the padding is called 'lefter', because it is even more to the left than # the actual attack bs = 16 lefter_size = find_lefter_pad_size(func, bs) return crack_ecb_simple(func, lefter_size) def find_lefter_pad_size(func: Callable[[bytes], bytes], bs: int = 16) -> int: reference = func(b"a" * bs) sample_pads = [b"a" * x + b"b" + b"a" * (bs - x) for x in range(bs)] sample_out = [find_diff(reference, func(sp)) for sp in sample_pads] offset = [ sample_out[i] - i for i in range(1, len(sample_out)) if sample_out[i - 1] != sample_out[i] ]
def test_oracle(self): if 'oracle' not in self.tests: self.skipTest("") expected = generate_bytes(randint(1, 5)) actual = encryption_oracle_ecb_cbc(expected, randint(1, 2) == 1) self.assertLess(len(expected), len(actual))
from functools import reduce from random import choice from typing import List from ch01 import from_base64, Base64 from ch10 import encrypt_cbc, decrypt_cbc, WrongPaddingException, strip_padding from ch11 import generate_bytes fixkey: bytes = generate_bytes() def encrypt_random_string(bs: int = 16, teststring: str = None) -> bytes: iv = generate_bytes() # noinspection PyTypeChecker strings: List[Base64] = ["MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=", "MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=", "MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==", "MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==", "MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl", "MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==", "MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==", "MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=", "MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=", "MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93"] rand_string = from_base64(choice(strings)) if teststring: rand_string = teststring return iv + encrypt_cbc(rand_string, fixkey, iv, bs) def decrypt_check_padding(data, bs: int = 16) -> bool: