from Crypto.Cipher import AES SUBMARINE_KEY = "YELLOW SUBMARINE" def ECB_decrypt(content, key=SUBMARINE_KEY): return AES.new(key, AES.MODE_ECB).decrypt(content) def ECB_encrypt(content, key=SUBMARINE_KEY): return AES.new(key, AES.MODE_ECB).encrypt(content) if __name__ == "__main__": import cryptopals as c content = c.b64decode(open('data/7.txt').read()) assert ECB_encrypt(ECB_decrypt(content)) == content print(ECB_decrypt(content))
SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw= VHJhbnNmb3JtZWQgdXR0ZXJseTo= QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4= """ def solve_keystream(lines): def best_char_for(index): def score(char): return sum( c.character_frequencies.get(chr(line[index] ^ char), 0) for line in lines if index < len(line)) return max(range(256), key=score) return bytearray(map(best_char_for, range(max(map(len, lines))))) def solve(lines, keystream): for l in lines: print(c.strxor(l, keystream)) if __name__ == "__main__": lines = [c.CTR_Encrypt(c.b64decode(s)) for s in text.split('\n')[1:-1]] keystream = solve_keystream(lines) incorrect_idx = len(lines[0]) - 1 keystream[incorrect_idx] ^= (ord('u') ^ ord('y')) solve(lines, keystream) # poem is "Easter, 1916" by William Butler Yeats.
copy = bytearray(ciphertext) final_offset = offset + len(newtext) begin = round_down(offset) end = round_up(final_offset) encrypt = partial(c.CTR_Encrypt, key=key, offset=begin) edited = bytearray(encrypt(ciphertext[begin:end])) edited[offset - begin:final_offset - begin] = newtext copy[begin:end] = encrypt(edited) return bytes(copy) def breakit(edit, ciphertext): def get_char_at(idx): for char in c.all_chars(): if edit(ciphertext, offset=idx, newtext=char) == ciphertext: return char raise ValueError("Couldn't break it!") return b''.join(map(get_char_at, range(len(ciphertext)))) if __name__ == "__main__": edit = partial(edit, key=c.RAND_KEY) decrypt = encrypt = partial(c.CTR_Encrypt, key=c.RAND_KEY) text = c.ECB_decrypt(c.b64decode(open('data/25.txt').read())) print(text) ciphertext = encrypt(text) print(breakit(edit, ciphertext))
import cryptopals as c from copy import copy text = """MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc= MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic= MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw== MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg== MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA== MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw== MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8= MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g= MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93""" strings = [c.b64decode(s) for s in text.split('\n')] def cookie(string): return (c.pad_CBC_encrypt(string, key=c.RAND_KEY), c.IV) def decrypt(cookie): return c.CBC_decrypt(cookie, key=c.RAND_KEY) def check(cookie): try: c.remove_padding(decrypt(cookie)) except ValueError: return False return True
import cryptopals as c from struct import pack def CTR_Encrypt(text, key=c.RAND_KEY, offset=0): text = c.as_bytes(text) start_block = offset // 16 # limit to 2 ** 32 bytes transfereed return b''.join( c.strxor( c.ECB_encrypt( b'\x00' * 8 + pack("<l", i + start_block) + b'\x00' * 4, key=key), block) for i, block in enumerate(c.blocks(text))) if __name__ == "__main__": print(CTR_Encrypt(c.b64decode('L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ=='), key=c.SUBMARINE_KEY))