def encryption_oracle(plaintext): random_key = get_random_bytes(16) random_iv = get_random_bytes(16) # print("Random key:", random_key) # print("Random iv:", random_iv) random_length = randint(5, 10) # print("Random length addition:",random_length) random_addition = get_random_bytes(random_length) # print("Random addition:", random_addition) plaintext = random_addition + plaintext + random_addition # print("Plaintext:", plaintext) choice = randint(1, 2) print("Choice:", choice) ciphertext = b"" cipher_ecb = ecb_module() cipher_cbc = cbc_module(random_iv, random_key) if choice == 1: print("Encryption engine: ECB") ciphertext = cipher_ecb.ecb_encrypt(plaintext, random_key) elif choice == 2: print("Encryption engine: CBC") ciphertext = cipher_cbc.cbc_encrypt(plaintext) return ciphertext
def main(): m1 = b'YELLOW SUBMARINE' m2 = b'The quick brown fox jumps over the lazy dog' expected_sha1_m1 = hashlib.sha1(m1).hexdigest() expected_sha1_m2 = hashlib.sha1(m2).hexdigest() sha1_m1 = SHA1Hash().process(m1).hexdigest() sha1_m2 = SHA1Hash().process(m2).hexdigest() print("Verify SHA-1 implementation works as expected") if sha1_m1 == expected_sha1_m1 and sha1_m2 == expected_sha1_m2: print("\nMessage 1: ", m1) print("Expected SHA1:", expected_sha1_m1) print("Calculated SHA1:", sha1_m1) print("\nMessage 2: ", m2) print("Expected SHA1:", expected_sha1_m2) print("Calculated SHA1:", sha1_m2) print("--- Success ---") else: raise Exception("*** FAILED ***") print("Verify Athenticated SHA-1 implementation works as expected:") m = b'The quick brown fox jumps over the lazy dog' key = get_random_bytes(16) auth_sha1_m = auth_SHA1(key, m) expected_auth_sha1_m = hashlib.sha1(key + m).hexdigest() if auth_sha1_m == expected_auth_sha1_m: print("\nMessage: ", m) print("Key:", key) print("Expected Auth_SHA1:", expected_auth_sha1_m) print("Calculated Auth_SHA1:", auth_sha1_m) print("--- Success ---") else: raise Exception("*** FAILED ***")
def encrypt_credentials(data, key=None): if not key: key = generate_key(KEY_BIT_LENGTH) print('The encryption key is: ' + b64encode(key).decode('utf8').rstrip('=')) else: key += '=' * ((4 - len(key) % 4) % 4) key = b64decode(key.encode('utf8')) new_data = dict() for item in data: item_data = data[item] if type(item_data) != OrderedDict or 'encrypted' not in item_data: to_encrypt = json.dumps(item_data, separators=(',', ':')).encode('utf8') nonce = get_random_bytes(int(ceil(NONCE_BIT_LENGTH / 8.0))) encrypted = encrypt(key, nonce, to_encrypt) new_data[item] = { 'encrypted': b64encode(encrypted).decode('utf8').rstrip('=') + b64encode(nonce).decode('utf8').rstrip('='), } else: new_data[item] = item_data return new_data
def MITM(): print("=== MITM ===") # Step 1 # A > M: Send p, g, A print("[+] Step 1: A > B - Send p, g, A") DH_A = DH() A = DH_A.generate_public_key(p, g) # Step 2 # M > B: Send p, g, p print("[*] Step 2 - Intercepted: M > B: Send p, g, p") A = p # Step 3 # B > M: Send B print("[+] Step 3: B > A - Send B") DH_B = DH() B = DH_B.generate_public_key(p, g) # Step 4 # M > A: Send p print("[*] Step 4 - Intercepted: M > A: Send p") B = p # Step 5 # A > M: Send AES-CBC(SHA1(s)[0:16], iv=random(16), msg) + iv encryption_key_A = DH_A.generate_encryption_key(B, p) iv_A = get_random_bytes(16) ciphertext_A = DH_A.encrypt(iv_A, encryption_key_A, secret_message) + iv_A print("[+] Step 5: A > B:", ciphertext_A) # Step 6 # M->B: Relay that to B print("[-] Step 6: M->B: Relay that to B") # Step 7 # B > M: Send AES-CBC(SHA1(s)[0:16], iv=random(16), A's msg) + iv encryption_key_B = DH_B.generate_encryption_key(A, p) iv_B = ciphertext_A[-16:] plaintext_AtoB = DH_B.decrypt(iv_B, encryption_key_B, ciphertext_A[:-16]) ciphertext_B = DH_B.encrypt(iv_B, encryption_key_B, plaintext_AtoB) + iv_B print("[+] Step 4: B > A:", ciphertext_B) # Step 8 # M > A: Relay that to A print("[-] Step 8: M > A: Relay that to A") # Step 9 DH_M = DH() encryption_key_M = DH_M.generate_encryption_key(p, p) iv_M = iv_B plaintext_M = DH_M.decrypt(iv_M, encryption_key_M, ciphertext_A[:-16]) print(plaintext_M) if plaintext_M == secret_message: print("--- Success ---") print("=== END ===")
def generate_v(self, I, P): x = 0 xH = '' salt = get_random_bytes(16) xH = hashlib.sha256(salt + P).hexdigest() x = int(xH, 16) v = pow(self.g, x, self.N) return v, salt
def encryption_oracle(plaintext): global random_key random_key = get_random_bytes(16) encoded_suffix = base64.b64decode( 'Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK' ) expanded_plaintext = random_prefix + plaintext + encoded_suffix cipher_ecb = ecb_module() ciphertext = cipher_ecb.ecb_encrypt(expanded_plaintext, random_key) return ciphertext
def main(): # 1. Write the function that does this for MT19937 using a 16-bit seed. Verify that you can encrypt and decrypt properly. print("\n1. Verifying MT19937_cipher is working as expected") test_plaintext = b'This is a random line that we would like to encrypt' test_MT19937_cipher(test_plaintext) print("\n2. Recover encryption seed from an expanded known plaintext") # 2. Use your function to encrypt a known plaintext (say, 14 consecutive 'A' characters) prefixed by a random number of random characters. From the ciphertext, recover the "key" (the 16 bit seed). seed = randint(0, 2**16) random_prefix = get_random_bytes(randint(0, 16)) target = b'AAAAAAAAAAAAAA' ciphertext = MT19937_cipher(seed).encrypt(random_prefix + target) cracked_seed = crack_MT19937_cipher(ciphertext, target) print("\n3. Check if MT19937 has been seeded with current time") # 3. Use the same idea to generate a random "password reset token" using MT19937 seeded from the current time. Write a function to check if any given password token is actually the product of an MT19937 PRNG seeded with the current time. seed = int(time()) random_prefix = get_random_bytes(randint(0, 16)) target = b'username' random_suffix = b';password_reset=true' plaintext = random_prefix + target + random_suffix ciphertext = MT19937_cipher(seed).encrypt(plaintext) cracked_seed = crack_MT19937_seed(ciphertext, target)
def private_protocol(): print("=== Standard Protocol ===") # Step 1 # A > B - Send p, g, A print("[+] Step 1: A > B - Send p, g, A") DH_A = DH() A = DH_A.generate_public_key(p, g) print("> p =", p) print("> g =", g) print("> A =", A) # Step 2 # B > A - Send B print("[+] Step 2: B > A - Send B") DH_B = DH() B = DH_B.generate_public_key(p, g) print("> B =", B) # Step 3 # A > B - Send AES-CBC(SHA1(s)[0:16], iv=random(16), msg) + iv #shared_secret_A = DH_A.generate_shared_secret(B, p) encryption_key_A = DH_A.generate_encryption_key(B, p) iv_A = get_random_bytes(16) #cipher_A = cbc_module(iv_A, encryption_key_A) ciphertext_A = DH_A.encrypt(iv_A, encryption_key_A, secret_message) + iv_A print("[+] Step 3: A > B:", ciphertext_A) # Step 4 # B > A - Send AES-CBC(SHA1(s)[0:16], iv=random(16), A's msg) + iv encryption_key_B = DH_B.generate_encryption_key(A, p) iv_B = ciphertext_A[-16:] plaintext_AtoB = DH_B.decrypt(iv_B, encryption_key_B, ciphertext_A[:-16]) ciphertext_B = DH_B.encrypt(iv_B, encryption_key_B, plaintext_AtoB) + iv_B print("[+] Step 4: B > A:", ciphertext_B) print("=== END ===")
def main(): ''' Because ECB is deterministic, i.e. the same plaintext will always produce the same ciphertexts, we know that the encoded profile for [email protected] will produce: [email protected]&uid=10&role=user That can be split in 16 bytes blocks with padding before encryption: [email protected] | m&uid=10&role=us | er + padding This is a chosen-ciphertext attack, custom email address are allowed. Let's pick: ''' email1 = '*****@*****.**' email2 = '*****@*****.**' + '\x0b' * 11 ''' Encoding the two email addresses: 16 bytes blocks for email1: [email protected] | om&uid=10&role= | user + padding 16 bytes blocks for email2: [email protected] | admin x0b * 11 | user + padding ''' random_key = get_random_bytes(16) encrypted_email1 = encrypt_profile(profile_for(email1), random_key) encrypted_email2 = encrypt_profile(profile_for(email2), random_key) ''' Swapping blocks ''' target1 = encrypted_email1[0:32] target2 = encrypted_email2[16:32] print(decrypt_profile(target1 + target2, random_key))
def generate_key(bit_length=KEY_BIT_LENGTH): return get_random_bytes(bit_length // 8)
Set 03 - Challenge 19 BREAK FIXED-NONCE CTR MODE USING SUBSTITUTIONS ''' import base64 import struct from set03challenge18 import ctr_module from os import urandom as get_random_bytes from set01challenge02 import xor_strings target = open('set03challenge19.txt', 'r').readlines() target_list = [base64.b64decode(line) for line in target] # Parameters key = get_random_bytes(16) nonce = struct.pack('Q', 0) # Expanded to 64bit little endian cipher = ctr_module(key, nonce) encrypted_target = [cipher.ctr(item) for item in target_list] def single_character_decryption(encrypted_target, i): # For each of the 256 possible guess-values: for guess in range(256): # Generate a list of all the 256 values of guess # XOR'd against the value at index i of each ciphertext decrypted = [ encrypted_item[i] ^ guess for encrypted_item in encrypted_target ] # If all the XOR'd values are characters in the list provided,
''' Matasano Crypto Challenges Set 02 - Challenge 14 BYTE-AT-A-TIME ECB DECRYPTION (HARD) ''' import base64 from os import urandom as get_random_bytes from random import randint from set02challenge11 import ecb_module global random_prefix random_prefix = get_random_bytes(randint(1, 32)) def encryption_oracle(plaintext): global random_key random_key = get_random_bytes(16) encoded_suffix = base64.b64decode( 'Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK' ) expanded_plaintext = random_prefix + plaintext + encoded_suffix cipher_ecb = ecb_module() ciphertext = cipher_ecb.ecb_encrypt(expanded_plaintext, random_key)