コード例 #1
0
def decode_repeating_byte_xor(ciphertext: bytes):
    c = ciphertext
    edit_distances = defaultdict(list)
    for keysize in range(2, 41):
        k, e = keysize, []
        e.append(normalised_hamming_distance(c[:k], c[k:k * 2]))
        e.append(normalised_hamming_distance(c[k * 2:k * 3], c[k * 3:k * 4]))
        e.append(normalised_hamming_distance(c[k * 3:k * 4], c[k * 4:k * 5]))
        e.append(normalised_hamming_distance(c[k * 4:k * 5], c[k * 5:k * 6]))
        edit_distances[sum(e) / 4].append(keysize)
    likely_keysizes = sorted(edit_distances.items())[:5]

    def reducing_func(x: List[int], y: Tuple[Any, List[int]]) -> List[Any]:
        return x + y[1]
    possible_keysizes = reduce(reducing_func, likely_keysizes, [])
    keys = []  # type: List[str]
    for keysize in possible_keysizes:
        blocks = split_into_groups(ciphertext, keysize)
        if len(blocks[-1]) != keysize:
            del blocks[-1]
        transposed_blocks = zip(*blocks)
        key = []
        for block in transposed_blocks:
            char, _ = decode_1_byte_xor(block)
            key.append(char)
        keys.append(''.join(key))
    keys = [x for x in keys if x]
    plaintexts = {}  # Dict[str, str]
    for key in keys:
        plaintexts[
            repeating_key_xor(
                ciphertext, bytes(key, 'ascii')).decode('ascii')] = key
    plaintext = find_english_text(plaintexts.keys())
    return plaintexts[plaintext], plaintext
コード例 #2
0
def aes_cbc_encode(plaintext: bytes, password: bytes, iv: bytes) -> bytes:
    blocks = split_into_groups(plaintext, 16)
    res = []
    prev_block = iv
    for block in blocks:
        prev_block = aes_ecb_encode(xor(prev_block, block), password)
        res.append(prev_block)
    return b''.join(res)
コード例 #3
0
def detect_aes_ecb_encrypted_texts(ciphertexts: List[bytes]):
    max_repeats = defaultdict(list)
    for text in ciphertexts:
        counts = Counter(split_into_groups(text, 16))
        most_no_of_repeats = counts.most_common(1)[0][1]
        max_repeats[most_no_of_repeats].append(text)
    most_repeats = max(max_repeats.keys())
    return most_repeats, max_repeats[most_repeats]
コード例 #4
0
def aes_cbc_decode(ciphertext: bytes, password: bytes, iv: bytes) -> bytes:
    blocks = split_into_groups(ciphertext, 16)
    res = []
    # Sort out the first block on its own, as it requires iv
    res.append(xor(aes_ecb_decode(blocks[0], password), iv))
    # Sort out all other blocks
    for i, block in enumerate(blocks[1:], 1):
        res.append(xor(aes_ecb_decode(block, password), blocks[i - 1]))
    return b''.join(res)