def _g_equal_p_minus_one() -> bool: g = _p - 1 a = DHClient(_p, g) b = DHClient(a.p, a.g) a.gen_session_key(b.public_key) b.gen_session_key(a.public_key) a_encrypted_msg = a.encrypt_msg(_msg) b_encrypted_msg = b.encrypt_msg(_msg) a_decrypted_msg = a.decrypt_msg(*b_encrypted_msg) b_decrypted_msg = b.decrypt_msg(*a_encrypted_msg) if a.public_key == g and b.public_key == g: key = g else: key = 1 key = sha1(key.to_bytes(floor(key.bit_length() / 8) + 1, "big"))[:16] iv = a_encrypted_msg[0] cbc = AESCipher(AESCipher.MODE_CBC, key, iv=iv) mitm_decrypted = pkcs7_unpad(cbc.decrypt(a_encrypted_msg[1])) return mitm_decrypted == a_decrypted_msg == b_decrypted_msg == _msg
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 decrypt_msg(self, iv: bytes, msg: bytes) -> bytes: key = sha1( self._session_key.to_bytes( floor(self._session_key.bit_length() / 8) + 1, "big"))[:16] cbc = AESCipher(AESCipher.MODE_CBC, key, iv=iv) return pkcs7_unpad(cbc.decrypt(msg))
def _edit(cipher_text: bytes, offset: int, new_text: bytes) -> bytes: ctr = AESCipher(AESCipher.MODE_CTR, _KEY, nonce=_NONCE) plain_text = ctr.decrypt(cipher_text) plain_text = plain_text[:offset] + new_text + plain_text[offset + len(new_text):] return ctr.encrypt(plain_text)
def _oracle(iv: bytes, ct: bytes) -> bool: cbc = AESCipher(AESCipher.MODE_CBC, _KEY, iv=iv) try: pkcs7_unpad(cbc.decrypt(ct)) except PKCS7Error: return False return True
def encrypt_msg(self, msg: bytes) -> Tuple[bytes, bytes]: key = sha1( self._session_key.to_bytes( floor(self._session_key.bit_length() / 8) + 1, "big"))[:16] iv = gen_random_bytes(16) cbc = AESCipher(AESCipher.MODE_CBC, key, iv=iv) return (iv, cbc.encrypt(pkcs7_pad(msg)))
def challenge07(path: str) -> bytes: key = b"YELLOW SUBMARINE" cipher = AESCipher(AESCipher.MODE_ECB, key) with open(path) as f: lines = f.readlines() cipher_text = base64.b64decode("".join(lines)) msg = cipher.decrypt(cipher_text).split(b"\n") return msg[0]
def challenge10(path: str) -> bytes: key = b"YELLOW SUBMARINE" iv = b"\x00" * 16 cipher = AESCipher(AESCipher.MODE_CBC, key, iv=iv) with open(path) as f: lines = f.readlines() cipher_text = base64.b64decode("".join(lines)) plain_text = cipher.decrypt(cipher_text).split(b"\n") return plain_text[0]
def challenge18() -> bool: ct = base64.b64decode( "L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==" ) result = b"Yo, VIP Let's kick it Ice, Ice, baby Ice, Ice, baby " key = b"YELLOW SUBMARINE" nonce = b"\x00" * 8 ctr = AESCipher(AESCipher.MODE_CTR, key, nonce=nonce, counter=0) res = ctr.decrypt(ct) return res == result
def test_aes_ecb_decrypt(self): # Test vectors from NIST Special Publication 800-38A 2001 Edition key = bytes.fromhex("2b7e151628aed2a6abf7158809cf4f3c") ct = bytes.fromhex("3ad77bb40d7a3660a89ecaf32466ef97" "f5d3d58503b9699de785895a96fdbaaf" "43b1cd7f598ece23881b00e3ed030688" "7b0c785e27e8ad3f8223207104725dd4") pt = bytes.fromhex("6bc1bee22e409f96e93d7e117393172a" "ae2d8a571e03ac9c9eb76fac45af8e51" "30c81c46a35ce411e5fbc1191a0a52ef" "f69f2445df4f9b17ad2b417be66c3710") ecb = AESCipher(AESCipher.MODE_ECB, key) result = ecb.decrypt(ct) assert result == pt, "The result does not match the expected value"
def test_aes_cbc_encrypt(self): # Test vectors from NIST Special Publication 800-38A 2001 Edition key = bytes.fromhex("2b7e151628aed2a6abf7158809cf4f3c") iv = bytes.fromhex("000102030405060708090a0b0c0d0e0f") pt = bytes.fromhex("6bc1bee22e409f96e93d7e117393172a" "ae2d8a571e03ac9c9eb76fac45af8e51" "30c81c46a35ce411e5fbc1191a0a52ef" "f69f2445df4f9b17ad2b417be66c3710") ct = bytes.fromhex("7649abac8119b246cee98e9b12e9197d" "5086cb9b507219ee95db113a917678b2" "73bed6b8e3c1743b7116e69e22229516" "3ff1caa1681fac09120eca307586e1a7") cbc = AESCipher(AESCipher.MODE_CBC, key, iv=iv) result = cbc.encrypt(pt) assert result == ct, "The result does not match the expected value"
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 challenge34() -> bool: p = int.from_bytes( bytes.fromhex("ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024" "e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd" "3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec" "6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f" "24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361" "c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552" "bb9ed529077096966d670c354e4abc9804f1746c08ca237327fff" "fffffffffffff"), "big", ) g = 2 msg = b"test" a = DHClient(p, g) b = DHClient(a.p, a.g) a.gen_session_key(b.p) b.gen_session_key(a.p) a_encrypted_msg = a.encrypt_msg(msg) b_encrypted_msg = b.encrypt_msg(msg) a_decrypted_msg = a.decrypt_msg(*b_encrypted_msg) b_decrypted_msg = b.decrypt_msg(*a_encrypted_msg) key = 0 key = sha1(key.to_bytes(floor(key.bit_length() / 8) + 1, "big"))[:16] iv = a_encrypted_msg[0] cbc = AESCipher(AESCipher.MODE_CBC, key, iv=iv) mitm_decrypted = pkcs7_unpad(cbc.decrypt(a_encrypted_msg[1])) return mitm_decrypted == a_decrypted_msg == b_decrypted_msg == msg
def test_aes_ctr_decrypt(self): key = bytes.fromhex("2b7e151628aed2a6abf7158809cf4f3c") nonce = bytes.fromhex("f0f1f2f3f4f5f6f7") counter = 0xF8F9FAFBFCFDFEFF ct = bytes.fromhex("874d6191b620e3261bef6864990db6ce" "9806f66b7970fdff8617187bb9fffdff" "5ae4df3edbd5d35e5b4f09020db03eab" "1e031dda2fbe03d1792170a0f3009cee") pt = bytes.fromhex("6bc1bee22e409f96e93d7e117393172a" "ae2d8a571e03ac9c9eb76fac45af8e51" "30c81c46a35ce411e5fbc1191a0a52ef" "f69f2445df4f9b17ad2b417be66c3710") cbc = AESCipher( AESCipher.MODE_CTR, key, nonce=nonce, counter=counter, counter_byteorder="big", ) result = cbc.decrypt(ct) assert result == pt, "The result does not match the expected value"
def _encrypt_it(path: str) -> (bytes, bytes): ecb = AESCipher(AESCipher.MODE_ECB, key=b"YELLOW SUBMARINE") with open(path) as f: cipher_text = base64.b64decode(f.read()) plain_text = ecb.decrypt(cipher_text) ctr = AESCipher(AESCipher.MODE_CTR, _KEY, nonce=_NONCE) cipher_text = ctr.encrypt(plain_text) return cipher_text, plain_text
def _encryption_oracle(bytes_: bytes) -> Tuple[bytes, str]: key = gen_random_bytes(16) iv = gen_random_bytes(16) prefix = gen_random_bytes(random.randint(5, 10)) suffix = gen_random_bytes(random.randint(5, 10)) pt = prefix + bytes_ + suffix cbc_mode = random.choice([True, False]) if cbc_mode: cbc = AESCipher(AESCipher.MODE_CBC, key, iv=iv) ct = cbc.encrypt(pkcs7_pad(pt)) answer = "cbc" else: ecb = AESCipher(AESCipher.MODE_ECB, key) ct = ecb.encrypt(pkcs7_pad(pt)) answer = "ecb" return ct, answer
#!/usr/bin/env python3 from urllib.parse import quote, unquote from functions.xor import xor_byte_arrays from functions.aes import AESCipher, gen_random_bytes, pkcs7_unpad, pkcs7_pad _ctr = AESCipher(AESCipher.MODE_CTR, gen_random_bytes(16), nonce=gen_random_bytes(8)) def _parse_cookie(string: str) -> dict: return { k: unquote(v) for k, v in [s.split("=", 1) for s in string.split(";")] } def _get_token(user_data: str) -> bytes: prefix = "comment1=cooking%20MCs;userdata=" suffix = ";comment2=%20like%20a%20pound%20of%20bacon" token = prefix + quote(user_data) + suffix return _ctr.encrypt(pkcs7_pad(token.encode("latin"))) def _is_admin(token: bytes) -> bool: decrypted_token = pkcs7_unpad(_ctr.decrypt(token)) cookie = _parse_cookie(decrypted_token.decode("latin"))
from functions.aes import gen_random_bytes, AESCipher, pkcs7_pad RESULT = b"""Rollin' in my 5.0 With my rag-top down so my hair can blow The girlies on standby waving just to say hi Did you stop? No, I just drove by """ _SECRET = base64.b64decode( "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg" "aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq" "dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg" "YnkK") _ecb = AESCipher(AESCipher.MODE_ECB, gen_random_bytes(16)) def _encrypt_it(bytes_: bytes) -> bytes: pt = bytes_ + _SECRET ct = _ecb.encrypt(pkcs7_pad(pt)) return ct def _get_info() -> Tuple[int, int]: length_without_padding = len(_encrypt_it(bytes())) length_with_padding = length_without_padding padding = bytes()
#!/usr/bin/env python3 from urllib.parse import quote, unquote from functions.xor import xor_byte_arrays from functions.aes import AESCipher, gen_random_bytes, pkcs7_unpad, pkcs7_pad _cbc = AESCipher(AESCipher.MODE_CBC, gen_random_bytes(16), iv=gen_random_bytes(16)) def _parse_cookie(string: str) -> dict: return { k: unquote(v) for k, v in [s.split("=", 1) for s in string.split(";")] } def _get_token(user_data: str) -> bytes: prefix = "comment1=cooking%20MCs;userdata=" suffix = ";comment2=%20like%20a%20pound%20of%20bacon" token = prefix + quote(user_data) + suffix return _cbc.encrypt(pkcs7_pad(token.encode("latin"))) def _is_admin(token: bytes) -> bool: decrypted_token = pkcs7_unpad(_cbc.decrypt(token)) cookie = _parse_cookie(decrypted_token.decode("latin"))
def _encrypt(pt: bytes) -> (bytes, bytes): iv = gen_random_bytes(16) cbc = AESCipher(AESCipher.MODE_CBC, _KEY, iv=iv) ct = cbc.encrypt(pkcs7_pad(pt)) return iv, ct
#!/usr/bin/env python3 from typing import Union from urllib.parse import quote, unquote from functions.aes import AESCipher, gen_random_bytes, pkcs7_unpad, pkcs7_pad from functions.xor import xor_byte_arrays _KEY = gen_random_bytes(16) _cbc = AESCipher(AESCipher.MODE_CBC, _KEY, iv=_KEY) def _parse_cookie(string: str) -> dict: return { k: unquote(v) for k, v in [s.split("=", 1) for s in string.split(";")] } def _get_token(user_data: str) -> bytes: prefix = "comment1=cooking%20MCs;userdata=" suffix = ";comment2=%20like%20a%20pound%20of%20bacon" token = prefix + quote(user_data) + suffix return _cbc.encrypt(pkcs7_pad(token.encode("latin"))) def _is_admin(token: bytes) -> Union[bool, Exception]: # decrypted_token = pkcs7_unpad(_cbc.decrypt(token)) decrypted_token = _cbc.decrypt(token)