示例#1
0
def detect_ecb_line(cipher_text, block_size=default_aes_block_size):
    '''
    :param cipher_text: hexdecimal bytes string or string
    :param block_size: block size used
    :return: number of unique blocks, line number and the cipher it self as a tuple
    '''
    min_unique_blocks = maxsize
    cipher_res = None
    cipher_line = 0

    for line_number, cipher in enumerate(cipher_text):
        if isinstance(cipher, bytes):
            cipher = cipher.decode('utf-8')

        unique_blocks = len(
            set(
                get_blocks(arr=hex_to_bytes(cipher.strip()),
                           block_size=block_size)))
        if unique_blocks < min_unique_blocks:
            min_unique_blocks = unique_blocks
            cipher_res = bytes(cipher.strip(), 'utf-8')
            cipher_line = line_number + 1

    min_unique_blocks = min_unique_blocks if min_unique_blocks < len(
        list(get_blocks(arr=hex_to_bytes(cipher_res),
                        block_size=block_size))) else None
    return min_unique_blocks, cipher_line, cipher_res
示例#2
0
def byte_byte_ecb_break(unknown_str, hard=False):
    '''
    :param unknown_str: unknown string we want to break as bytes string
    :param hard: if this hard ECB decryption
    :return: the discoverd string as bytes string
    '''
    prefix_text = b'' if not hard else _urandom(randint(0, 100))
    enc, dec = random_key_ecb_enc_dec(prefix_text, unknown_str)

    def single_block_break(block):
        discovered = b''

        for i in range(len(block) - 1, -1, -1):
            prepad = b'A' * i
            expected_cipher = enc(
                plain_text=b''.join([prepad, block])[:len(block)])

            for c in range(256):
                test = prepad + discovered + bytes([c])

                if enc(plain_text=test) == expected_cipher:
                    discovered += bytes([c])
                    break

        return discovered

    res = b''
    for block in get_blocks(arr=unknown_str,
                            block_size=find_block_size(enc_func=enc)):
        res += single_block_break(block=block)

    return res
示例#3
0
    def encrypt(self, plain_text):
        data = pad(data=plain_text, block_size=AES.block_size)
        cipher = []
        iv = self.__iv
        for block in get_blocks(arr=data, block_size=AES.block_size):
            iv = self.__block_encrypt_ecb(plain_text=xor_strings(iv, block))
            cipher.append(iv)

        return b''.join(cipher)
示例#4
0
def decode_base64(base64_bytes):
    '''
    :param base64_bytes: base64 bytes string
    :return: bytes string of the decoded base64 bytes in hexadecimal
    '''
    chars_in_block = 4
    ret = b''

    for block in get_blocks(arr=base64_bytes, block_size=chars_in_block):
        bin_bits_to_trim = block.count(b'=') * 2
        bin_arr = ''.join([
            base64_char_to_bin(base64_char=chr(c)) for c in block
            if c != ord('=')
        ])
        bin_arr = bin_arr[:len(bin_arr) - bin_bits_to_trim]
        for bin_block in get_blocks(arr=bin_arr, block_size=8):
            ret += bin_str_to_hex(bin_str=bin_block)

    return ret
示例#5
0
    def decrypt(self, cipher_text):
        plain = []
        iv = self.__iv
        for block in get_blocks(arr=cipher_text, block_size=AES.block_size):
            plain.append(
                xor_strings(iv, self.__block_decrypt_ecb(cipher_text=block)))
            iv = block

        plain[len(plain) - 1] = unpad(data=plain[len(plain) - 1])
        return b''.join(plain)
示例#6
0
def encode_base64(hex_bytes):
    '''
    :param hex_bytes: bytes string that contains hexadecimal numbers
    :return: byte string base64 representation of the input hex bytes
    '''
    ret = b''
    bytes_in_block = 3
    padded, padded_bytes = pad_base64_bytes(hex_bytes=hex_bytes)
    bits_encode = 0

    for block in get_blocks(arr=padded, block_size=bytes_in_block):
        bin_arr = ''.join(
            [hex_byte_to_bin(block[i]) for i in range(bytes_in_block)])
        for bin_block in get_blocks(arr=bin_arr, block_size=6):
            ret += bytes(BASE64_TBL[int(bin_block, 2)], 'utf-8') if bits_encode <= (len(padded)*8 - (padded_bytes*8))\
                else bytes('=', 'utf-8')

            bits_encode += 6

    return ret
示例#7
0
    def find_key_size(cipher_text, start_range, end_range):
        distances = []
        for key_size in range(start_range, end_range):
            blocks = list(get_blocks(arr=cipher_text, block_size=key_size))
            hamming_distance_sum = 0
            for b1, b2 in zip(blocks[::2], blocks[1::2]):
                hamming_distance_sum += hamming_distance(b1, b2)
            distances.append(
                (key_size,
                 ((hamming_distance_sum / len(blocks) / 2) / key_size)))

        return sorted(distances, key=itemgetter(1))[0]
示例#8
0
def repeated_key_xor_breaker(cipher_text):
    '''
    :param cipher_text: cipher text as hexadecimal bytes string
    :return: decryption of the cipher text as bytes string
    '''
    def find_key_size(cipher_text, start_range, end_range):
        distances = []
        for key_size in range(start_range, end_range):
            blocks = list(get_blocks(arr=cipher_text, block_size=key_size))
            hamming_distance_sum = 0
            for b1, b2 in zip(blocks[::2], blocks[1::2]):
                hamming_distance_sum += hamming_distance(b1, b2)
            distances.append(
                (key_size,
                 ((hamming_distance_sum / len(blocks) / 2) / key_size)))

        return sorted(distances, key=itemgetter(1))[0]

    key = []
    cipher_text_hex_bytes = hex_to_bytes(cipher_text)
    key_size = find_key_size(cipher_text=cipher_text_hex_bytes,
                             start_range=2,
                             end_range=41)[0]
    blocks = [
        list(block)
        for block in get_blocks(arr=cipher_text_hex_bytes, block_size=key_size)
        if len(block) == key_size
    ]

    for block in zip(*blocks):
        key.append(
            single_byte_xor_breaker(bytes_to_hex(bytes([x
                                                        for x in block])))[1])

    return hex_to_bytes(
        repeated_key_xor(plain_text=hex_to_bytes(cipher_text),
                         key=bytes(key))), bytes(key)