Example #1
0
def test_parity():
    key = key_1024

    print("\nTest: parity")
    plaintext1 = bytes(b"Some plaintext ") + random_bytes(10) + bytes(
        b" anything can it be")
    plaintext2 = bytes(b"Some plaintext ") + random_bytes(10) + bytes(
        b" anything can it be2")
    ciphertext1 = h2b(
        subprocess.check_output([
            "python", rsa_oracles_path, "encrypt", key.identifier,
            b2h(plaintext1)
        ]).strip().decode())
    ciphertext2 = h2b(
        subprocess.check_output([
            "python", rsa_oracles_path, "encrypt", key.identifier,
            b2h(plaintext2)
        ]).strip().decode())

    key.texts.append({'cipher': b2i(ciphertext1)})
    key.texts.append({'cipher': b2i(ciphertext2)})
    msgs_recovered = parity(parity_oracle, key.publickey())
    assert msgs_recovered[0] == b2i(plaintext1)
    assert msgs_recovered[1] == b2i(plaintext2)
    key.clear_texts()
Example #2
0
def test_blinding():
    global key_to_oracle
    key = key_2048
    key_to_oracle = key

    print("\nTest: blinding(key, signing_oracle=signing_oracle)")
    for _ in range(10):
        msg_to_sign = b2i(
            random_bytes(randint(10, (key.size / 8) - 1)).replace(
                bytes(b'\n'), bytes(b'')))
        key.add_plaintext(msg_to_sign)
        signature = blinding(key, signing_oracle=signing_oracle)
        assert len(signature) == 1
        is_correct = subprocess.check_output([
            "python", rsa_oracles_path, "verify", key_to_oracle.identifier,
            i2h(msg_to_sign),
            i2h(signature[0])
        ]).strip().decode()
        assert is_correct == 'True'
        key.clear_texts()

    print("\nTest: blinding(key, decryption_oracle=decryption_oracle)")
    for _ in range(10):
        plaintext = b2i(
            random_bytes(randint(10, (key.size / 8) - 1)).replace(
                bytes(b'\n'), bytes(b'')))
        ciphertext = key.encrypt(plaintext)
        key.add_ciphertext(ciphertext)
        plaintext_recovered = blinding(key,
                                       decryption_oracle=decryption_oracle)
        assert len(plaintext_recovered) == 1
        assert plaintext_recovered[0] == plaintext
        key.clear_texts()

    key_to_oracle = None
Example #3
0
def find_prefix_suffix_size(encryption_oracle, block_size=16):
    """Determine prefix and suffix sizes if ecb mode, sizes must be constant
    Rarely may fail (if random data that are send unhappily matches prefix/suffix)

    Args:
        encryption_oracle(callable)
        block_size(int)

    Returns:
        tuple(int,int): prefix_size, suffix_size
    """
    blocks_to_send = 5
    payload = random_bytes(1) * (blocks_to_send * block_size)
    enc_chunks = chunks(encryption_oracle(payload), block_size)
    log.debug("Encryption of length {}".format(blocks_to_send * block_size))
    log.debug(print_chunks(enc_chunks))

    for position_start in range(len(enc_chunks) - 1):
        if enc_chunks[position_start] == enc_chunks[position_start + 1]:
            for y in range(2, blocks_to_send - 1):
                if enc_chunks[position_start] != enc_chunks[position_start + y]:
                    break
            else:
                log.success("Controlled payload start at chunk {}".format(position_start))
                break
    else:
        log.critical_error("Position of controlled chunks not found")

    log.info('Finding prefix')
    changed_char = bytes([(payload[0] - 1)%256])
    for aligned_bytes in range(block_size):
        payload_new = payload[:aligned_bytes] + changed_char + payload[aligned_bytes+1:]
        enc_chunks_new = chunks(encryption_oracle(payload_new), block_size)
        log.debug(print_chunks(chunks(payload_new, block_size)))
        log.debug(print_chunks(enc_chunks_new))
        if enc_chunks_new[position_start] != enc_chunks[position_start]:
            prefix_size = position_start*block_size - aligned_bytes
            log.success("Prefix size: {}".format(prefix_size))
            break
    else:
        log.critical_error("Size of prefix not found")

    log.info('Finding suffix')
    payload = random_bytes(1) * (block_size - (prefix_size % block_size))  # align to block_size
    encrypted = encryption_oracle(payload)
    suffix_size = len(encrypted) - len(payload) - prefix_size
    while True:
        payload += random_bytes(1)
        suffix_size -= 1
        if len(encryption_oracle(payload)) > len(encrypted):
            log.success("Suffix size: {}".format(suffix_size))
            break
    else:
        log.critical_error("Size of suffix not found")

    return prefix_size, suffix_size
Example #4
0
def test_fake_ciphertext_decryption_oracle(amount=5):
    for _ in range(amount):
        new_plaintext = random_bytes(randint(1, 10))
        new_plaintext_padded = add_padding(new_plaintext, block_size)

        print("Test small: cbc.fake_ciphertext(new_plaintext_padded, decryption_oracle=decryption_oracle)")
        new_ciphertext = cbc.fake_ciphertext(new_plaintext_padded, decryption_oracle=decryption_oracle)
        decrypted = h2b(subprocess.check_output(
            ['python', cbc_oracles_path, 'decrypt', b2h(new_ciphertext)]).strip().decode())
        assert decrypted == new_plaintext

    for _ in range(amount):
        new_plaintext = random_bytes(randint(10, 50))
        new_plaintext_padded = add_padding(new_plaintext, block_size)

        print("Test large: cbc.fake_ciphertext(new_plaintext_padded, decryption_oracle=decryption_oracle)")
        new_ciphertext = cbc.fake_ciphertext(new_plaintext_padded, decryption_oracle=decryption_oracle, padding_oracle=padding_oracle)
        decrypted = h2b(subprocess.check_output(
            ['python', cbc_oracles_path, 'decrypt', b2h(new_ciphertext)]).strip().decode())
        assert decrypted == new_plaintext
Example #5
0
def test_small_e_msg():
    key = key_1024_small_e
    print("\nTest: small_e_msg")
    for _ in range(10):
        plaintext = b2i(random_bytes(10))
        ciphertext = key.encrypt(plaintext)
        key.add_ciphertext(ciphertext)
        recovered_plaintext = small_e_msg(key)
        assert len(recovered_plaintext) == 1
        assert recovered_plaintext[0] == plaintext
        key.clear_texts()

    for _ in range(10):
        plaintext = b2i(random_bytes(42))
        ciphertext = key.encrypt(plaintext)
        key.add_ciphertext(ciphertext)
        recovered_plaintext = small_e_msg(key)
        assert len(recovered_plaintext) == 1
        assert recovered_plaintext[0] == plaintext
        key.clear_texts()
Example #6
0
def test_length_extension():
    print("Test length extension sha1")
    for x in range(30):
        secret = random_bytes(random.randint(0, 130))
        new_message = random_bytes(random.randint(0, 130))
        old_hash = sha1(secret)
        new_hash, new_data = length_extension(old_hash,
                                              len(secret),
                                              new_message,
                                              type='sha1')
        assert sha1(secret + new_data) == new_hash

    print("Test length extension md4")
    for x in range(30):
        secret = random_bytes(random.randint(0, 130))
        new_message = random_bytes(random.randint(0, 130))
        old_hash = md4(secret)
        new_hash, new_data = length_extension(old_hash,
                                              len(secret),
                                              new_message,
                                              type='md4')
        assert md4(secret + new_data) == new_hash
Example #7
0
def test_RSAKey():
    print("\nTest: RSAKey")
    key = RSAKey.generate(2048)
    key2 = RSAKey(key.n, key.e)
    assert key2.n == key.n

    key2 = RSAKey(key.n, key.e, d=key.d)
    assert key2.p == key.p or key2.q == key.p

    key2 = RSAKey(key.n, key.e, p=key.q)
    assert key2.d == key.d

    for _ in range(10):
        tmp = random_bytes(randint(1, key.size // 8 - 10))
        assert key.decrypt(key.encrypt(tmp)) == b2i(tmp)
Example #8
0
def test_decrypt():
    global constant, prefix_len, suffix_len, secret
    print(
        "test: ecb.decrypt(encryption_oracle_aes, constant, block_size=AES.block_size)"
    )
    constant = True
    for x in range(20):
        prefix_len = random.randint(0, 90)
        secret = random_bytes(random.randint(1, 90))
        print("Secret to guess(hex): {}".format(b2h(secret)))
        guessed_secret = ecb.decrypt(encryption_oracle_aes,
                                     constant,
                                     block_size=AES.block_size)
        assert secret == guessed_secret
        guessed_secret = ecb.decrypt(encryption_oracle_des,
                                     constant,
                                     block_size=DES3.block_size)
        assert secret == guessed_secret
Example #9
0
def test_iv_as_key(from_test=1):
    global iv_as_key
    iv_as_key = True
    plaintext = random_bytes(randint(1, 40))
    plaintext_padded = add_padding(plaintext, block_size)
    ciphertext = encrypt(plaintext, iv_as_key=iv_as_key)

    if from_test <= 1:
        print("Test 1: cbc.iv_as_key()")
        key = cbc.iv_as_key(ciphertext[AES.block_size:], plaintext_padded, padding_oracle=padding_oracle)
        assert key == KEY

    if from_test <= 2:
        print("Test 2: cbc.iv_as_key()")
        key = cbc.iv_as_key(ciphertext[AES.block_size:], plaintext_padded, decryption_oracle=decryption_oracle)
        assert key == KEY

    iv_as_key = False
Example #10
0
def find_block_size(encryption_oracle, constant=True):
    """Determine block size if ecb mode

    Args:
        encryption_oracle(callable)
        constant(bool): True if prefix and suffix have constant length

    Returns:
        int
    """
    if constant:
        log.debug("constant == True")
        payload = bytes(b'A')
        size = len(encryption_oracle(payload))
        while True:
            payload += bytes(b'A')
            new_size = len(encryption_oracle(payload))
            if new_size > size:
                log.info("block_size={}".format(new_size - size))
                return new_size - size
    else:
        log.debug("constant == False")
        payload = bytes(b'A')
        max_size = len(encryption_oracle(payload))
        possible_sizes = factors(max_size)
        possible_sizes.add(max_size)
        blocks_to_send = 5

        for block_size in sorted(possible_sizes):
            """send payload of length x, so at least x-1 blocks should be identical"""
            payload = random_bytes(1) * (blocks_to_send*block_size)
            enc_chunks = chunks(encryption_oracle(payload), block_size)
            for x in range(len(enc_chunks)-1):
                if enc_chunks[x] == enc_chunks[x+1]:
                    log.debug("Found two identical blocks at {}: {}".format(x, print_chunks(enc_chunks)))
                    for y in range(2, blocks_to_send-1):
                        if enc_chunks[x] != enc_chunks[x+y]:
                            break
                    else:
                        log.info("block_size={}".format(block_size))
                        return block_size
Example #11
0
def encryption_oracle_des(payload):
    global constant, prefix_len, suffix_len, secret
    if secret:
        if constant:
            payload = random_bytes(prefix_len) + payload + secret
        else:
            payload = random_bytes(random.randint(1, 50)) + payload + secret
    else:
        if constant:
            payload = random_bytes(prefix_len) + payload + random_bytes(
                suffix_len)
        else:
            payload = random_bytes(random.randint(
                1, 50)) + payload + random_bytes(random.randint(1, 50))

    payload = add_padding(payload, DES3.block_size)
    cipher = DES3.new(key_DES3, DES3.MODE_ECB)
    return cipher.encrypt(payload)
Example #12
0
def decrypt(encryption_oracle, constant=True, block_size=16, prefix_size=None, secret_size=None,
            alphabet=None):
    """Given encryption oracle which produce ecb(prefix || our_input || secret), find secret
    
    Args:
        encryption_oracle(callable)
        constant(bool): True if prefix have constant length (secret must have constant length)
        block_size(int/None)
        prefix_size(int/None)
        secret_size(int/None)
        alphabet(string): plaintext space
    
    Returns:
        secret(string)
    """
    log.debug("Start decrypt function")
    if not alphabet:
        alphabet = bytes(string.printable.encode())

    if not block_size:
        block_size = find_block_size(encryption_oracle, constant)

    if constant:
        log.debug("constant == True")
        if not prefix_size or not secret_size:
            prefix_size, secret_size = find_prefix_suffix_size(encryption_oracle, block_size)

        """Start decrypt"""
        secret = bytes(b'')
        aligned_bytes = random_bytes(1) * (block_size - (prefix_size % block_size))
        if len(aligned_bytes) == block_size:
            aligned_bytes = bytes(b'')

        aligned_bytes_suffix = random_bytes(1) * (block_size - (secret_size % block_size))
        if len(aligned_bytes_suffix) == block_size:
            aligned_bytes_suffix = bytes(b'')

        block_to_find_position = -1
        controlled_block_position = (prefix_size+len(aligned_bytes)) // block_size

        while len(secret) < secret_size:
            if (len(secret)+1) % block_size == 0:
                block_to_find_position -= 1
            payload = aligned_bytes + aligned_bytes_suffix + random_bytes(1) + secret
            enc_chunks = chunks(encryption_oracle(payload), block_size)
            block_to_find = enc_chunks[block_to_find_position]

            log.debug("To guess at position {}:".format(block_to_find_position))
            log.debug("Plain: " + print_chunks(chunks(bytes(b'P'*prefix_size) + payload + bytes(b'S'*secret_size), block_size)))
            log.debug("Encry: " + print_chunks(enc_chunks)+"\n")

            for guessed_char in range(256):
                guessed_char = bytes([guessed_char])
                payload = aligned_bytes + add_padding(guessed_char + secret, block_size)
                enc_chunks = chunks(encryption_oracle(payload), block_size)

                log.debug("Plain: " + print_chunks(chunks(bytes(b'P'*prefix_size) + payload + bytes(b'S'*secret_size), block_size)))
                log.debug("Encry: " + print_chunks(enc_chunks)+"\n")
                if block_to_find == enc_chunks[controlled_block_position]:
                    secret = guessed_char + secret
                    log.debug("Found char, secret={}".format(repr(secret)))
                    break
            else:
                log.critical_error("Char not found, try change alphabet. Secret so far: {}".format(repr(secret)))
        log.success("Secret(hex): {}".format(b2h(secret)))
        return secret
    else:
        log.debug("constant == False")
Example #13
0
def bleichenbacher_signature_forgery(key,
                                     garbage='suffix',
                                     hash_function='sha1'):
    """Bleichenbacher's signature forgery based on bug in verify implementation

    Args:
        key(RSAKey): with small e and at least one plaintext
        garbage(string): middle: 00 01 ff garbage 00 ASN.1 HASH
                         suffix: 00 01 ff 00 ASN.1 HASH garbage
        hash_function(string)

    Returns:
        dict: forged signatures, signatures[no] == signature(key.texts[no]['plain'])
        update key texts
    """
    hash_asn1 = {
        'md5':
        bytes(
            b'\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10'
        ),
        'sha1':
        bytes(b'\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'),
        'sha256':
        bytes(
            b'\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20'
        ),
        'sha384':
        bytes(
            b'\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30'
        ),
        'sha512':
        bytes(
            b'\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40'
        )
    }
    if garbage not in ['suffix', 'middle']:
        log.critical_error("Bad garbage position, must be suffix or middle")
    if hash_function not in list(hash_asn1.keys()):
        log.critical_error(
            "Hash function {} not implemented".format(hash_function))

    if key.e > 3:
        log.debug("May not work, because e > 3")

    signatures = {}
    if garbage == 'suffix':
        for text_no in range(len(key.texts)):
            if 'plain' in key.texts[text_no] and 'cipher' not in key.texts[
                    text_no]:
                log.info("Forge for plaintext no {} ({})".format(
                    text_no, key.texts[text_no]['plain']))

                hash_callable = getattr(hashlib, hash_function)(i2b(
                    key.texts[text_no]
                    ['plain'])).digest()  # hack to call hashlib.hash_function
                plaintext_prefix = bytes(b'\x00\x01\xff\x00') + hash_asn1[
                    hash_function] + hash_callable

                plaintext = plaintext_prefix + bytes(
                    b'\x00' * (key.size // 8 - len(plaintext_prefix)))
                plaintext = b2i(plaintext)
                for round_error in range(-5, 5):
                    signature, _ = gmpy2.iroot(plaintext, key.e)
                    signature = int(signature + round_error)
                    test_prefix = i2b(gmpy2.powmod(signature, key.e, key.n),
                                      size=key.size)[:len(plaintext_prefix)]
                    if test_prefix == plaintext_prefix:
                        log.info("Got signature: {}".format(signature))
                        log.debug("signature**e % n == {}".format(
                            i2h(gmpy2.powmod(signature, key.e, key.n),
                                size=key.size)))
                        key.texts[text_no]['cipher'] = signature
                        signatures[text_no] = signature
                        break
                else:
                    log.error(
                        "Something wrong, can't compute correct signature")
        return signatures

    elif garbage == 'middle':
        for text_no in range(len(key.texts)):
            if 'plain' in key.texts[text_no] and 'cipher' not in key.texts[
                    text_no]:
                log.info("Forge for plaintext no {} ({})".format(
                    text_no, key.texts[text_no]['plain']))
                hash_callable = getattr(hashlib, hash_function)(i2b(
                    key.texts[text_no]
                    ['plain'])).digest()  # hack to call hashlib.hash_function
                plaintext_suffix = bytes(
                    b'\x00') + hash_asn1[hash_function] + hash_callable
                if b2i(plaintext_suffix) & 1 != 1:
                    log.error(
                        "Plaintext suffix is even, can't compute signature")
                    continue

                # compute suffix
                signature_suffix = 0b1
                for b in range(len(plaintext_suffix) * 8):
                    if (signature_suffix**
                            3) & (1 << b) != b2i(plaintext_suffix) & (1 << b):
                        signature_suffix |= 1 << b
                signature_suffix = i2b(
                    signature_suffix)[-len(plaintext_suffix):]

                # compute prefix
                while True:
                    plaintext_prefix = bytes(b'\x00\x01\xff') + random_bytes(
                        key.size // 8 - 3)
                    signature_prefix, _ = gmpy2.iroot(b2i(plaintext_prefix),
                                                      key.e)
                    signature_prefix = i2b(
                        int(signature_prefix),
                        size=key.size)[:-len(signature_suffix)]

                    signature = b2i(signature_prefix + signature_suffix)
                    test_plaintext = i2b(gmpy2.powmod(signature, key.e, key.n),
                                         size=key.size)
                    if bytes(b'\x00'
                             ) not in test_plaintext[2:-len(plaintext_suffix)]:
                        if test_plaintext[:3] == plaintext_prefix[:3] and test_plaintext[
                                -len(plaintext_suffix):] == plaintext_suffix:
                            log.info("Got signature: {}".format(signature))
                            key.texts[text_no]['cipher'] = signature
                            signatures[text_no] = signature
                            break
                        else:
                            log.error("Something wrong, signature={},"
                                      " signature**{}%{} is {}".format(
                                          signature, key.e, key.n,
                                          [(test_plaintext)]))
                            break
        return signatures
Example #14
0
def test_sha1():
    print("Test: sha1")
    for x in range(30):
        tmp = random_bytes(random.randint(0, 256))
        assert sha1(tmp) == hashlib.sha1(tmp).digest()
Example #15
0
def encrypt(data, iv_as_key=False):
    iv = random_bytes(block_size)
    if iv_as_key:
        iv = KEY
    aes = AES.new(KEY, AES.MODE_CBC, iv)
    return iv + bytes(aes.encrypt(add_padding(data)))
Example #16
0
from __future__ import absolute_import, division, print_function

import random
from builtins import range

from Crypto.Cipher import AES, DES3

from CryptoAttacks.Block import ecb
from CryptoAttacks.Utils import add_padding, b2h, log, random_bytes

block_size = AES.block_size
prefix_len = 13
suffix_len = 19
constant = True
key_AES = random_bytes(AES.key_size[-1])
key_DES3 = random_bytes(DES3.key_size[-1])
secret = None


def encryption_oracle_aes(payload):
    global constant, prefix_len, suffix_len, secret
    if secret:
        if constant:
            payload = random_bytes(prefix_len) + payload + secret
        else:
            payload = random_bytes(random.randint(1, 50)) + payload + secret
    else:
        if constant:
            payload = random_bytes(prefix_len) + payload + random_bytes(
                suffix_len)
Example #17
0
def test_decrypt(from_test=1):
    original_plaintext = random_bytes(randint(1, 40))
    original_ciphertext = encrypt(original_plaintext)
    original_plaintext = add_padding(original_plaintext, block_size)

    if from_test <= 1:
        print("Test 1: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True)")
        decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True)
        assert decrypted == original_plaintext

    if from_test <= 2:
        data = original_ciphertext[:-block_size - 1] + bytes(b'A') + original_ciphertext[-block_size:]
        print("Test 2: cbc.decrypt(data, padding_oracle=padding_oracle, is_correct=False)")
        decrypted = cbc.decrypt(data, padding_oracle=padding_oracle, is_correct=False)
        assert decrypted[-block_size:-1] == original_plaintext[-block_size:-1]

    if from_test <= 3:
        print("Test 3: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=False)")
        decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=False)
        assert decrypted[:-1] == original_plaintext[:-1]

    if from_test <= 4:
        iv = original_ciphertext[:block_size]
        data = original_ciphertext[block_size:]
        print("Test 4: cbc.decrypt(data, padding_oracle=padding_oracle, iv=iv)")
        decrypted = cbc.decrypt(data, padding_oracle=padding_oracle, iv=iv)
        assert decrypted == original_plaintext

    if from_test <= 5:
        if len(original_plaintext) > block_size:
            print("Test 5: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, amount=2)")
            decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, amount=2)
            assert decrypted == original_plaintext[-block_size * 2:]

    if from_test <= 6:
        print("Test 6: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, amount=1, is_correct=True)")
        decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, amount=1, is_correct=True)
        assert decrypted == original_plaintext[-block_size:]

    if from_test <= 7:
        print("Test 7: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True, \n \
                                 known_plaintext=original_plaintext)")
        decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True,
                                known_plaintext=original_plaintext)
        assert decrypted == original_plaintext

    if from_test <= 8:
        print("Test 8: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True, \n \
                                 known_plaintext=original_plaintext[-4:])")
        decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True,
                                known_plaintext=original_plaintext[-4:])
        assert decrypted == original_plaintext

    if from_test <= 9:
        print("Test 9: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True, \n \
                                 known_plaintext=original_plaintext[-7:], amount=1)")
        decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True,
                                known_plaintext=original_plaintext[-7:], amount=1)
        assert decrypted == original_plaintext[-block_size:]

    if from_test <= 10:
        print("Test 10: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=False, \n \
                                 known_plaintext=original_plaintext[-7:], amount=1)")
        decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=False,
                                known_plaintext=original_plaintext[-7:], amount=1)
        assert decrypted == original_plaintext[-block_size:]

    if from_test <= 11:
        print("Test 11: cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True, \n \
                                 known_plaintext=original_plaintext[-block_size - 3:])")
        decrypted = cbc.decrypt(original_ciphertext, padding_oracle=padding_oracle, is_correct=True,
                                known_plaintext=original_plaintext[-block_size - 3:])
        assert decrypted == original_plaintext

    if from_test <= 12:
        print("Test 12: cbc.decrypt(original_ciphertext, decryption_oracle=decryption_oracle, is_correct=True, \n \
                                 known_plaintext=original_plaintext[-block_size - 3:])")
        decrypted = cbc.decrypt(original_ciphertext, decryption_oracle=decryption_oracle,
                                known_plaintext=original_plaintext[-block_size - 3:], is_correct=True)
        assert decrypted == original_plaintext

    if from_test <= 13:
        print("Test 13: cbc.decrypt(original_ciphertext, decryption_oracle=decryption_oracle)")
        decrypted = cbc.decrypt(original_ciphertext, decryption_oracle=decryption_oracle)
        assert decrypted == original_plaintext
Example #18
0
def test_bleichenbacher_signature_forgery():
    key = key_1024_small_e
    print(
        "\nTest bleichenbacher_signature_forgery(key, garbage='suffix', hash_function='sha1')"
    )
    for _ in range(10):
        message1 = bytes(b"Some plaintext ") + random_bytes(10) + bytes(
            b" anything can it be")
        message2 = bytes(b"Some plaintext ") + random_bytes(10) + bytes(
            b" anything can it be")

        key.add_plaintext(b2i(message1))
        key.add_plaintext(b2i(message2))

        forged_signatures = bleichenbacher_signature_forgery(
            key, garbage='suffix', hash_function='sha1')
        assert len(forged_signatures) == 2

        verify_signature1 = subprocess.check_output([
            "python", rsa_oracles_path, "verify_bleichenbacher_suffix",
            key.identifier,
            b2h(message1),
            i2h(forged_signatures[0]), 'sha1'
        ]).strip().decode()
        assert verify_signature1 == 'True'
        verify_signature2 = subprocess.check_output([
            "python", rsa_oracles_path, "verify_bleichenbacher_suffix",
            key.identifier,
            b2h(message2),
            i2h(forged_signatures[1]), 'sha1'
        ]).strip().decode()
        assert verify_signature2 == 'True'
        key.clear_texts()

    print(
        "\nTest bleichenbacher_signature_forgery(key, garbage='middle', hash_function='sha1')"
    )
    for _ in range(10):
        message1 = bytes(b"Some plaintext ") + random_bytes(10) + bytes(
            b" anything can it be")
        message2 = bytes(b"Some plaintext ") + random_bytes(10) + bytes(
            b" anything can it be")

        key.add_plaintext(b2i(message1))
        key.add_plaintext(b2i(message2))

        forged_signatures = bleichenbacher_signature_forgery(
            key, garbage='middle', hash_function='sha1')
        print(forged_signatures)

        # first plaintext signed
        if 0 in forged_signatures:
            verify_signature1 = subprocess.check_output([
                "python", rsa_oracles_path, "verify_bleichenbacher_middle",
                key.identifier,
                b2h(message1),
                i2h(forged_signatures[0]), 'sha1'
            ]).strip().decode()
            assert verify_signature1 == 'True'

        # second plaintext signed
        if 1 in forged_signatures:
            verify_signature2 = subprocess.check_output([
                "python", rsa_oracles_path, "verify_bleichenbacher_middle",
                key.identifier,
                b2h(message2),
                i2h(forged_signatures[1]), 'sha1'
            ]).strip().decode()
            assert verify_signature2 == 'True'
        key.clear_texts()