Beispiel #1
0
def encrypt_aes_128_cbc(key, iv, plainbuf):
    block_size = 16

    if len(key) != 16:
        print "key must be 16 bytes long"
        return

    if len(iv) != block_size:
        print "iv must be %d bytes long" % block_size
        return

    encbuf = []
    last_enc_block = iv
    for i in range(0, len(plainbuf), block_size):
        plain_block = plainbuf[i:i + block_size]

        if len(plain_block) != block_size:
            print "plain_block requires %d bytes of padding" % (
                block_size - len(plain_block))
            return

        round1 = challenge5.repeating_xor(plain_block, last_enc_block)

        aes = AES.new(key)
        enc_block = aes.encrypt(round1)
        encbuf.append(enc_block)

        last_enc_block = enc_block

    encbuf = "".join(encbuf)

    return encbuf
Beispiel #2
0
def print_plaintexts(ciphertexts, key_stream, marker=None):
    plaintexts = []
    for i, ciphertext in enumerate(ciphertexts):
        plaintext = challenge5.repeating_xor(ciphertext, key_stream)
        plaintexts.append(plaintext)

        if marker is not None:
            plaintext = plaintext[:marker] + "|||" + plaintext[marker:]

        print "%d: %s" % (i, repr(plaintext))

    return plaintexts
Beispiel #3
0
def aes_cbc_decrypt(key, iv, stream):
    fail_msg = "stream should be a multiple of %d, size actually: %d" \
           % (BLOCK_SIZE_IN_BYTES, len(stream))
    assert len(stream) % BLOCK_SIZE_IN_BYTES == 0, fail_msg

    blocks = block_split(stream)

    last_block = None
    result = []
    for idx, ct_block in enumerate(blocks):
        if idx == 0:
            last_block = iv

        pt_block = repeating_xor(last_block, aes_ecb_decrypt(key, ct_block))
        last_block = ct_block
        result.append(pt_block)

    return bytes().join(result)
Beispiel #4
0
def aes_cbc_encrypt(key, iv, stream):
    fail_msg = "stream should be a multiple of %d, size actually: %d" \
           % (BLOCK_SIZE_IN_BYTES, len(stream))
    assert len(stream) % BLOCK_SIZE_IN_BYTES == 0, fail_msg

    blocks = block_split(stream)

    result = []
    for idx, pt_block in enumerate(blocks):
        last_block = iv if idx == 0 else result[-1]

        # pad block if its too small...
        # TODO: should only be needed on the last block
        if len(pt_block) < BLOCK_SIZE_IN_BYTES:
            pt_block = pkcs7_pad(pt_block, BLOCK_SIZE_IN_BYTES)

        ct_block = aes_ecb_encrypt(key, repeating_xor(last_block, pt_block))
        result.append(ct_block)

    return bytes().join(result)
Beispiel #5
0
def break_vigenere(x):
    # find the key size by taking the minimum edit distance
    edit_dsts = []
    for key_sz in KEY_SZS:
        ct_chunks = chunk(x, key_sz)
        paired_ct_chunks = [(ct_chunks[i], ct_chunks[i + 1])
                            for i in range(0, len(ct_chunks), 2)
                            if i + 1 < len(ct_chunks)]
        edit_dst = 0.0
        for x_1, x_2 in paired_ct_chunks:
            edit_dst += float(edit_dist(x_1, x_2)) / key_sz
        edit_dst = edit_dst / len(paired_ct_chunks)
        edit_dsts.append(edit_dst)

    min_edit_dst = min(edit_dsts)
    guessed_key_sz = KEY_SZS[edit_dsts.index(min_edit_dst)]
    print(f"[*] Guessed key size: {guessed_key_sz}")

    ct_chunks = chunk(x, guessed_key_sz)

    # transpose the blocks
    ct_chunks_t = transpose_blks(ct_chunks)

    # solve each block as a single-character XOR
    key = bytearray([])
    for ct_chunk_t in ct_chunks_t:
        c, _ = bruteforce_single_byte(bytes_to_hex(ct_chunk_t))
        key += bytearray([ord(c)])

    # get the key
    print(f"[*] Key found: {key}")

    # get the plaintext (hopefully!)
    pt_hex = repeating_xor(x, key)
    pt = hex_to_bytearray(pt_hex)

    return key, pt
def decrypt_message() -> None:
    decrypt_key = get_decrypt_key()
    message = repeating_xor(cipher, decrypt_key)
    print(message.decode())
Beispiel #7
0
import challenge18


def get_ciphertexts(plaintexts):
    rand_key = challenge11.get_rand_bytes(16)

    ciphertexts = []
    for plaintext in plaintexts:
        aes_128_ctr = challenge18.AES128CTR(key=rand_key, nonce=0, counter=0)
        ciphertext = aes_128_ctr.crypt(base64.b64decode(plaintext))
        ciphertexts.append(ciphertext)

    return ciphertexts


if __name__ == "__main__":
    fp = open("20.txt", "rb")
    lines = fp.readlines()
    fp.close()
    lines = [l.strip() for l in lines]

    ciphertexts = get_ciphertexts(lines)

    smallest_len = min([len(c) for c in ciphertexts])
    truncated_ciphertexts = [c[:smallest_len] for c in ciphertexts]
    concatenated_ciphertexts = "".join(truncated_ciphertexts)

    key = challenge6.get_probable_key(concatenated_ciphertexts, smallest_len, smallest_len+1)
    concatenated_plaintexts = challenge5.repeating_xor(concatenated_ciphertexts, key)
    print concatenated_plaintexts
Beispiel #8
0
            if score >= high_score:
                high_score = score
                single_byte_key = test_key

        probable_key.append(chr(single_byte_key))

    probable_key = "".join(probable_key)
    print "probable key: %s" % repr(probable_key)

    return probable_key


if __name__ == "__main__":
    # test hamming_distance
    if hamming_distance("this is a test", "wokka wokka!!!") != 37:
        print "bad hamming distance func"
        sys.exit(1)

    # break repeating xor key
    fp = open("6.txt", "rb")
    data = fp.read()
    fp.close()

    data = data.strip("\n")
    round1 = base64.b64decode(data)

    key = get_probable_key(round1, 2, 41)

    print
    print challenge5.repeating_xor(round1, key)