def hmac_sha1(key, message): if len(key) > block_size: key = sha1(key).digest() if len(key) < block_size: key += (block_size - len(key)) * b'\x00' o_key_pad = fixed_xor(key, b'\x5c' * block_size) i_key_pad = fixed_xor(key, b'\x36' * block_size) return sha1(o_key_pad + sha1(i_key_pad + message).digest()).digest()
def modify_ciphertext_ctr(ciphertext): _, plaintext = authenticate(ciphertext) print_split_blocks(plaintext) # This is the ciphertext xor-red with the plaintext # plaintext = ciphertext ^ keystream # ciphertext = plaintext ^ keystream # comment1=cooking|%20MCs;userdata=|hacker;comment2=|%20like%20a%20po|und%20of%20bacon # print(len(plaintext), len(ciphertext)) keystream = fixed_xor(ciphertext, plaintext) # print(keystream) # print(len(keystream)) new_plaintext = bytearray(plaintext) new_plaintext[32:48] = b'a;admin=true;c2=' new_plaintext = bytes(new_plaintext) new_ciphertext = fixed_xor(new_plaintext, keystream) return new_ciphertext
def modify_ciphertext(ciphertext): # if we modify a certain block, it will be xor-ed with the ciphertext in the block after. new_ciphertext = bytearray(ciphertext) # this gives us the plaintext "comment1=whatever;userdata=hacker;commment2=whatever" block_print() # keep stdout clean _, plaintext = authenticate(ciphertext) enable_print() # b'comment1=cooking|%20MCs;userdata=|hacker;comment2=|%20like%20a%20po|und%20of%20bacon' # Unchanged Unchanged Scrambled We Control Unchanged to_xor = fixed_xor(plaintext[48:64], b'a;admin=true;ab=') to_xor = pack('16B', *to_xor) new_ciphertext[32:48] = fixed_xor(new_ciphertext[32:48], to_xor) print_split_blocks_hex(ciphertext) print_split_blocks_hex(new_ciphertext) # we know that the plaintext return bytes(new_ciphertext)
def aes_ctr_crypt(text, key, nonce): othertext = bytearray() counter = 0 aes = AES.new(key) for block in split_blocks(text): encrypted = aes.encrypt(pack('<qq', nonce, counter)) othertext += fixed_xor(encrypted[:len(block)], block) counter += 1 return bytes(othertext)
def repeating_key(binary_string, binary_key): binary_list = list(binary_string) # "Burning 'em" -> ["B", "u", ...] key_list = repeat_to_length(binary_key, len(binary_list)) result = [] for a,b in zip(binary_list, key_list): result.append(challenge2.fixed_xor(a,b)) return ''.join(map(str,result))
def test_set2(self): text = fixed_xor('1c0111001f010100061a024b53535009181c', '686974207468652062756c6c277320657965') self.assertEqual(text, '0x746865206b696420646f6e277420706c6179')
def single_xor(binary, ascii_code): return challenge2.fixed_xor(binary, chr(ascii_code) * len(binary))
def crypt_mtr(text, seed): mt = MersenneTwister() mt.seed_mt(seed) keystream = b''.join( [struct.pack('I', mt.extract_number()) for _ in range(len(text))]) return fixed_xor(text, keystream, True)
import challenge3, challenge2 import sys f = open("/Users/jacobhammontree/Projects/cryptopals/set1/challenge4.data", "r") lines = [] for l in f: lines.append((l[0:len(l) - 1])) lowest_score = sys.maxsize results = {} for l in lines: analysis = challenge3.freq_analysis_get_key(l) key = analysis[0] * (len(l) // 2) pt_candidate = challenge2.fixed_xor(l, key) pt_chunked = [ pt_candidate[i:i + 2] for i in range(0, len(pt_candidate), 2) ] stringed = "" for c in pt_chunked: stringed += chr(int(c, 16)) results[analysis[1]] = stringed print(results[min(results.keys())], min(results.keys())) print(sorted(results.keys()))