def bit_flip_CTR(CTR_oracle, target_bytes): ''' Flip bits in CBC cipher to produce target bytes at target block.''' insertion = bytes(16) work_cipher = CTR_oracle(insertion) # Assuming we know the point at which our insertion is entered into this; # it would be harder otherwise. We'll xor the cipher vs. our insertion. keystream_section = bytes_xor(work_cipher[32:48], insertion) # Now we xor the known section of keystream_section vs. our target_bytes. # This is simpler than CBC bitflipping. second_insertion = bytes_xor(keystream_section, target_bytes) return work_cipher[:32] + second_insertion + work_cipher[48:]
def bit_flip_CBC(CBC_oracle, target_bytes, target_block, b_l=16): ''' Flip bits in CBC cipher to produce target bytes at target block.''' insertion = bytes(16) work_cipher = CBC_oracle(insertion) # We know this is the plaintext; if we didn't, we would double our Z insertion. plaintext_to_be_flipped = b';comment2=%20lik' # The zero point that produced our known plaintext is this block; we need # to treat it as the base from which we work. insertion_cipher_block = work_cipher[32:48] # Find the xor product of the target and known plaintext. bytes_to_produce_target = bytes_xor(plaintext_to_be_flipped, target_bytes) # Combine that product with the base cipherblock. flipped_bits = bytes_xor(insertion_cipher_block, bytes_to_produce_target) flipped_cipher = work_cipher[:32] + flipped_bits + work_cipher[48:] return flipped_cipher
ciphers, if an English sentence is detected, return decryption.''' min_len = min([len(cipher) for cipher in list_of_ciphers]) possible_key_streams = product(*possible_key_bytes) dictionary = ct.load_dictionary() for key_stream in possible_key_streams: concat = b''.join(key_stream) for cipher in list_of_ciphers: work_cipher = cipher[:len(concat)] decryption = b''.join( [bytes([a ^ b]) for a, b in zip(cipher, concat)]) if ct.is_language(decryption, dictionary): print('Likely key stream found.') return concat else: print('Unable to find key stream.') return None static_key = os.urandom(16) nonce = struct.pack('<Q', 0) list_of_ciphers = make_ciphers(encrypt_AES_CTR, static_key, nonce, PLAINTEXTS) nonce_slices = concatenate_nonce_slices(list_of_ciphers) possible_key_stream = score_bytes(nonce_slices) likely_key_stream = try_likely_bytes(possible_key_stream, list_of_ciphers) if likely_key_stream: for cipher in list_of_ciphers: work_cipher = cipher[:len(likely_key_stream)] print(ct.bytes_xor(work_cipher, likely_key_stream))
def retrieve_key(unencrypted): ''' From plaintext of unencrypted remix cipher, retrieve IV used as key.''' return bytes_xor(unencrypted[:16], unencrypted[32:48])
min_len = min([len(cipher) for cipher in list_of_ciphers]) possible_key_streams = product(*possible_key_bytes) dictionary = ct.load_dictionary() for key_stream in possible_key_streams: concat = b''.join(key_stream) for cipher in list_of_ciphers: work_cipher = cipher[:len(concat)] decryption = b''.join([bytes([a ^ b]) for a,b in zip(cipher, concat)]) if ct.is_language(decryption, dictionary): print('Likely key stream found.') return concat else: print('Unable to find key stream.') return None static_key = os.urandom(16) nonce = struct.pack('<Q', 0) list_of_ciphers = make_ciphers(encrypt_AES_CTR, static_key, nonce, PLAINTEXTS) nonce_slices = concatenate_nonce_slices(list_of_ciphers) possible_key_stream = score_bytes(nonce_slices) likely_key_stream = try_likely_bytes(possible_key_stream, list_of_ciphers) if likely_key_stream: for cipher in list_of_ciphers: work_cipher = cipher[:len(likely_key_stream)] print(ct.bytes_xor(work_cipher, likely_key_stream))
def xor_hexes(hex_one, hex_two): bytes_one = ct.hex_to_bytes(hex_one) bytes_two = ct.hex_to_bytes(hex_two) xored_bytes = ct.bytes_xor(bytes_one, bytes_two) return ct.bytes_to_hex(xored_bytes)