Esempio n. 1
0
def ctr_transform(plain, key, nonce):
    plain_blocks = split_blocks(plain, 16)
    cipher_blocks = []
    keystream = ctr_aes128_keystream_gen(key, nonce)
    for block in plain_blocks:
        ks_block = next(keystream)
        cipher_blocks.append(xor_bytes(ks_block, block))
    return b''.join(cipher_blocks)
Esempio n. 2
0
def char_xor(input_bytes, char_byte):
    """ xors each char of input with char_byte. Returns bytestring"""
    for x in [input_bytes, char_byte]:
        try:
            x = x.decode()
        except AttributeError:
            pass
    key = len(input_bytes) * char_byte
    return xor_bytes(input_bytes, key)
Esempio n. 3
0
def cbc_decrypt_block(c_previous, pre_plain_current):
    """
    in
    :c_previous -- the last cipherblock (or IV if first block)
    :pre_p_current -- the decrypted current cipherblock
    out
    :p _current
    """
    return xor_bytes(c_previous, pre_plain_current)
Esempio n. 4
0
def cbc_encrypt_block(c_previous, p_current, key):
    """
    in
    :key -- key to encrypt the block
    :c_previous -- the last cipher_block
    :p_current -- the plain block to eb encrypted
    out
    :c_current -- the encrypted block
    """
    return encrypt_ecb_aes(xor_bytes(c_previous, p_current), key, False)
Esempio n. 5
0
def cbc_byteflip(func, target_plain, base_plain, blocksize, prefix_length=0):
    if max(len(target_plain), len(base_plain)) > blocksize:
        raise ValueError("Attack does not support targets larger than blocksize")
    elif len(target_plain) != len(base_plain):
        raise ValueError("target_plain and base_plain have to be of equal length")
    offset = 0
    if prefix_length % blocksize != 0:
        offset = blocksize - prefix_length % blocksize
    padd_start = b'A' * offset + b'A' * blocksize
    base_cipher_blocks = tools.split_blocks(func(padd_start + base_plain), blocksize)
    target_index = (prefix_length + offset) // blocksize
    target_block = base_cipher_blocks[target_index]
    padd_block = bytes(blocksize - len(target_plain))
    base_plain += padd_block
    target_plain += padd_block
    # generate modified cipher_block
    diff = tools.xor_bytes(target_plain, base_plain)
    new_block = tools.xor_bytes(diff, target_block)
    mod_cipher_blocks = base_cipher_blocks[:]
    mod_cipher_blocks[target_index] = new_block
    return b''.join(mod_cipher_blocks)
Esempio n. 6
0
def cbc_po_block(oracle, prev_c_block, target_c_block):
    """ decrypts a block via cbc paddingcoracle """
    blocksize = len(target_c_block)
    plain = b''
    for i in range(1, blocksize+1):
        pre = prev_c_block[:-i]
        post = tools.xor_bytes(bytes([i]*(i-1)), prev_c_block[-i+1:])
        post = tools.xor_bytes(post, plain[-i+1:])
        for guess in range(0, 256):
            x = bytes([guess ^ prev_c_block[-i] ^ i])  # guess xor prev_cipher xor padding
            mod_block = pre + x + post
            # print("oracle: ", mod_block, target_c_block)
            if oracle(mod_block+target_c_block):
                # TODO maybe check for false pos by modifying last byte of pre
                if i < blocksize:
                    mod_block = pre[:-1]+bytes([pre[-1]+1])+x+post
                    if oracle(mod_block+target_c_block):
                        plain = bytes([guess]) + plain
                else:
                    plain = bytes([guess]) + plain
    return plain
Esempio n. 7
0
def hamming(bytes_a, bytes_b):
    """takes 2 bytestrings and calculates the hamming distance"""
    for inp in [bytes_a, bytes_b]:
        try:
            inp = inp.encode()
        except AttributeError:
            pass
    dist = 0
    diff = xor_bytes(bytes_a, bytes_b)
    for char in diff:
        dist += str(bin(char)).count('1')
    return dist
Esempio n. 8
0
def main():
    length = len(base_ciphertext)
    dummy = bytes(length)
    key_stream = edit(0, dummy)
    solution = xor_bytes(key_stream, base_ciphertext)
    print(solution.decode())