def cbc_encrypt(key, plaintext, iv): plaintext = set2_ch9.padding(plaintext, 16) blocks = list(set1_ch6.chunks(plaintext, 16)) prev_encrypt = iv ciphertext = [] for b in blocks: xored = set1_ch2.xor(b, prev_encrypt) prev_encrypt = set1_ch7.encrypt(key, xored) ciphertext.append(prev_encrypt) return b"".join(ciphertext)
def exploit_cbc_oracle(iv, ciphertext): blocks = [iv] + list(set1_ch6.chunks(ciphertext, 16)) message = b'' # decrypted message we are uncovering # decrypt by block for b_num in range(len(blocks)-1): guessed = bytearray([0] * 16) # guessed characters # start from end of block for b in range(15, -1, -1): padding = bytearray([0] * 16) padding[b:16] = [16-b] * (16-b) # xor prev block, padding block, and guessed block modified = set1_ch2.xor(set1_ch2.xor(blocks[b_num], padding), guessed) # try every possible character until padding is valid for i in range(256): r = bytearray([0] * 16) r[b] = i xored = set1_ch2.xor(modified,r) if padding_oracle(xored + blocks[b_num+1]): if not (16-b == 1 and i == 1): # check special case of actual padding guessed[b] = i message += codecs.decode(guessed, 'base64') return message
def cbc_decrypt_wo_unpad(key, ciphertext, iv): blocks = list(set1_ch6.chunks(ciphertext, 16)) prev_block = iv plaintext = [] for b in blocks: decrypted = set1_ch7.decrypt(key, b) plaintext.append(set1_ch2.xor(decrypted, prev_block)) prev_block = b joined = b"".join(plaintext) return joined
def single_xor_score(cipher, key): decode = codecs.decode(cipher, 'hex') key_multiple = [key] * len(decode) res = set1_ch2.xor(decode, key_multiple) return res, key, scoring(str(res))
def repeat_xor(key, message): key_repeat = key * -(-len(message)//3) xor = set1_ch2.xor(message,key_repeat) return codecs.encode(xor, 'hex')