def _aes_cbc_decrypt(self, ciphertext: bytes) -> bytes: if len(ciphertext) % self._block_size: raise AESError("bad ciphertext length") ct_blocks = get_blocks(ciphertext) pt = bytes() pt += xor_byte_arrays(self._aes.decrypt(ct_blocks[0]), self._iv) for i in range(1, len(ct_blocks)): pt += xor_byte_arrays(self._aes.decrypt(ct_blocks[i]), ct_blocks[i - 1]) return pt
def challenge20(path: str) -> bool: with open(path) as f: lines = f.readlines() plain_texts = [base64.b64decode(s) for s in lines] secrets = [] for i in range(len(plain_texts)): ctr = AESCipher(AESCipher.MODE_CTR, _KEY, nonce=_NONCE) secrets.append(ctr.encrypt(plain_texts[i])) max_len = max(len(s) for s in secrets) keystream = bytearray() for i in range(max_len): i = len(keystream) char_chain = bytes([s[i] for s in secrets if len(s) > i]) possible_keys = rank_xor_single_byte_key(char_chain) key_byte = possible_keys[_FIX_MAP.get(i, 0)] keystream += key_byte pt = [xor_byte_arrays(s, keystream) for s in secrets] if pt == plain_texts: return True return False
def challenge04(path: str) -> bytes: with open(path) as file: ciphers = [bytes.fromhex(line) for line in file.readlines()] strings = [ xor_byte_arrays(cipher, bruteforce_xor_single_byte_key(cipher)) for cipher in ciphers ] msg = max(strings, key=calc_score).split(b"\n") return msg[0]
def _attacker() -> bytes: # A <-> ; | hex(ord("A") ^ ord(";")) = '0x7a' # B <-> = | hex(ord("B") ^ ord("=")) = '0x7f' data = "a" * 16 + "AadminBtrueAabBa" token = _get_token(data) ct_block = token[48:64] bitflip_block = b"\x7a\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x7a\x00\x00\x7f\x00" fixed_block = xor_byte_arrays(bitflip_block, ct_block) fixed_token = token[:48] + fixed_block + token[64:] return fixed_token
def challenge25(path: str) -> bool: cipher_text, plain_text = _encrypt_it(path) keystream = _edit(cipher_text, 0, bytes([0]) * len(cipher_text)) pt = xor_byte_arrays(cipher_text, keystream) if pt == plain_text: return True return False
def _attacker() -> bytes: token = _get_token("") new_token = token[:16] + bytes([0]) * 16 + token[:16] try: _is_admin(new_token) except Exception as e: decrypted = e.args[0] key = xor_byte_arrays(decrypted[:16], decrypted[32:]) return key
def _aes_cbc_encrypt(self, plaintext: bytes) -> bytes: if len(plaintext) % self._block_size: raise AESError("bad plaintext length") pt_blocks = get_blocks(plaintext) ct = bytes() block = self._iv for i in range(len(pt_blocks)): block = self._aes.encrypt(xor_byte_arrays(pt_blocks[i], block)) ct += block return ct
def _aes_ctr_encrypt(self, plaintext: bytes) -> bytes: length = len(plaintext) // self._block_size + ( len(plaintext) % self._block_size > 0) pt_blocks = get_blocks(plaintext) ct = bytes() counter = self._counter for i in range(length): ct += xor_byte_arrays( pt_blocks[i], self._aes.encrypt( self._nonce + counter.to_bytes(8, byteorder=self._counter_byteorder)), ) counter += 1 return ct
def challenge19() -> bool: secrets = [] for i in range(len(_STRINGS)): ctr = AESCipher(AESCipher.MODE_CTR, _KEY, nonce=_NONCE) secrets.append(ctr.encrypt(_STRINGS[i])) max_len = max(len(s) for s in secrets) keystream = bytearray() for i in range(max_len): char_chain = bytes([s[i] for s in secrets if len(s) > i]) possible_keys = rank_xor_single_byte_key(char_chain) key_byte = possible_keys[_FIX_MAP.get(i, 0)] keystream += key_byte pt = [xor_byte_arrays(s, keystream) for s in secrets] if pt == _STRINGS: return True return False
def challenge03(cipher: bytes) -> bytes: key = bruteforce_xor_single_byte_key(cipher) msg = xor_byte_arrays(cipher, key) return msg
def challenge02(first: bytes, second: bytes) -> bytes: return xor_byte_arrays(first, second)
def challenge05(text: bytes, key: bytes) -> bytes: cipher = xor_byte_arrays(text, key) return cipher