Example #1
0
def decrypt_by_crt(messages, public_key):
    """
    Requires that messages is an array of tuples of the form (ciphertext_i, n_i),
    where ciphertext_i for each i is the same message message m that is
    encrypted by m^public_key mod n_i.  Attempts an attack based on the
    Chinese Remainder theorem to compute m^public_key_key mod (n_1 * n_2 * ...).
    Here the hope is that m^public_key is not large compared to (n_1 * n_2 * ...)
    so that we can recover the original message by just taking
    (ciphertext_i - n_i * k)^(1/public_key) where k is fairly small.
    Of course this attack only works if (ciphertext_i, n_i) are all
    encryptions of the same original message (with identical padding),
    encrypted with the same (small) public.
    Returns None if unable to decrypt the messages.
    """
    print("Attempting decryption using CRT")
    crt_system = [(bits_to_int(string_to_bits(message[0])), message[1])
                  for message in messages]

    crt_solution = solve_crt_system(crt_system)

    # Recover the original message by taking the public_key root
    MAX_CRT_ROOT_TRIES = 10
    for i in range(MAX_CRT_ROOT_TRIES):
        root_result = gmpy2.iroot(
            gmpy2.mpz(crt_solution[0] + crt_solution[1] * i), public_key)

        if root_result[1]:
            oaep_padded_plaintext_int = root_result[0]
            return remove_oaep_from_plaintext(oaep_padded_plaintext_int,
                                              crt_system[0][1])

    return None
Example #2
0
def decrypt_by_crt(messages, public_key):
    """
    Requires that messages is an array of tuples of the form (ciphertext_i, n_i),
    where ciphertext_i for each i is the same message message m that is
    encrypted by m^public_key mod n_i.  Attempts an attack based on the
    Chinese Remainder theorem to compute m^public_key_key mod (n_1 * n_2 * ...).
    Here the hope is that m^public_key is not large compared to (n_1 * n_2 * ...)
    so that we can recover the original message by just taking
    (ciphertext_i - n_i * k)^(1/public_key) where k is fairly small.
    Of course this attack only works if (ciphertext_i, n_i) are all
    encryptions of the same original message (with identical padding),
    encrypted with the same (small) public.
    Returns None if unable to decrypt the messages.
    """
    print("Attempting decryption using CRT")
    crt_system = [(bits_to_int(string_to_bits(message[0])), message[1]) for message in messages]

    crt_solution = solve_crt_system(crt_system)
    
    # Recover the original message by taking the public_key root
    MAX_CRT_ROOT_TRIES = 10
    for i in range(MAX_CRT_ROOT_TRIES):
        root_result = gmpy2.iroot(gmpy2.mpz(crt_solution[0] + crt_solution[1] * i), public_key)    
    
        if root_result[1]:
            oaep_padded_plaintext_int = root_result[0]
            return remove_oaep_from_plaintext(oaep_padded_plaintext_int, crt_system[0][1])

    return None
Example #3
0
def decrypt(ciphertext, n, private_key, g, h):
    """
    Decrypts the specified ciphertext.
    Assumes that ciphertext was obtained by applying OAEP padding to a message
    (using parameters g and h), and then RSA-encrypted with parameter n and public
    key corresponding to the specified private_key.
    """
    ciphertext_int = bits_to_int(ciphertext)
    plaintext_int = pow(ciphertext_int, private_key, n)
    return decode_oaep(plaintext_int + n, g, h)
Example #4
0
def deliver_hint(recipient, hint_str):
    """
    Establish an encrypted session with the specified recipient
    and send hint_str.
    """
    initialization_response = initialize(recipient[0])
    session_token = initialization_response['token']

    pg = get_pg()
    p = int(pg['p'], 16)
    g = int(pg['g'], 16)

    eve_key_response_int = pow(g, X_EVE, p)
    eve_key_response = hex(eve_key_response_int)[2:]  # chop off the "0x"

    key_received_response = send_key(recipient[0], session_token,
                                     eve_key_response, "Eve")

    (ctr_key,
     ctr_nonce) = get_ctr_info(X_EVE, int(initialization_response['public'],
                                          16))

    initial_message = receive_msg(recipient[0], session_token)

    decrypted_message = counter_mode_encrypt(initial_message['msg'], ctr_key,
                                             initial_message['iv'], ctr_nonce)
    decrypted_message_str = bits_to_string(decrypted_message)
    print("decrypted_message_str", decrypted_message_str)

    hint_hex = hex(bits_to_int(string_to_bits(hint_str)))[2:]
    encrypted_hint = counter_mode_encrypt(hint_hex, ctr_key,
                                          initial_message['iv'], ctr_nonce)
    encrypted_hint_hex = hex(bits_to_int(encrypted_hint))[2:]

    response = send_msg(recipient[0], session_token, encrypted_hint_hex,
                        initial_message['iv'])

    decrypted_message = counter_mode_encrypt(response['reply']['msg'], ctr_key,
                                             response['reply']['iv'],
                                             ctr_nonce)
    decrypted_message_str = bits_to_string(decrypted_message)
    print("decrypted_message_str", decrypted_message_str)
Example #5
0
def deliver_hint(recipient, hint_str):
    """
    Establish an encrypted session with the specified recipient
    and send hint_str.
    """
    initialization_response = initialize(recipient[0])
    session_token = initialization_response['token']
    
    pg = get_pg()
    p = int(pg['p'], 16)
    g = int(pg['g'], 16)

    eve_key_response_int = pow(g, X_EVE, p)
    eve_key_response = hex(eve_key_response_int)[2:] # chop off the "0x"
    
    key_received_response = send_key(recipient[0], session_token,
            eve_key_response, "Eve")
    
    (ctr_key, ctr_nonce) = get_ctr_info(X_EVE, int(initialization_response['public'], 16))
    
    initial_message = receive_msg(recipient[0], session_token)
    
    
    decrypted_message = counter_mode_encrypt(initial_message['msg'], ctr_key, initial_message['iv'], ctr_nonce)
    decrypted_message_str = bits_to_string(decrypted_message)
    print("decrypted_message_str", decrypted_message_str)
    
    hint_hex = hex(bits_to_int(string_to_bits(hint_str)))[2:]
    encrypted_hint = counter_mode_encrypt(hint_hex, ctr_key, initial_message['iv'], ctr_nonce)
    encrypted_hint_hex = hex(bits_to_int(encrypted_hint))[2:]
    
    response = send_msg(recipient[0], session_token,
            encrypted_hint_hex, initial_message['iv'])
    
    decrypted_message = counter_mode_encrypt(response['reply']['msg'], ctr_key, response['reply']['iv'], ctr_nonce)
    decrypted_message_str = bits_to_string(decrypted_message)
    print("decrypted_message_str", decrypted_message_str)
Example #6
0
def retrieve_plaintext(ciphertext, private_key, n):
    """
    Given the specified ciphertext string encrypted using the specified private_key
    and n value, returns the decrypted plaintext.  Removes oaep if necessary.
    """
    ciphertext_bits = pad_bits(string_to_bits(ciphertext), MESSAGE_CHARS * ASCII_BITS)
    ciphertext_int = bits_to_int(ciphertext_bits)
    padded_plaintext_int = pow(ciphertext_int, private_key, n)

    # If the message wasn't padded, we'll detect that here.
    padded_plaintext_bits = pad_bits(convert_to_bits(padded_plaintext_int), len(ciphertext_bits))
    plaintext_string = bits_to_string(padded_plaintext_bits).strip('\x00')
    if is_valid_message(plaintext_string):
        return plaintext_string
    else:
        return remove_oaep_from_plaintext(padded_plaintext_int, n)
Example #7
0
def retrieve_plaintext(ciphertext, private_key, n):
    """
    Given the specified ciphertext string encrypted using the specified private_key
    and n value, returns the decrypted plaintext.  Removes oaep if necessary.
    """
    ciphertext_bits = pad_bits(string_to_bits(ciphertext),
                               MESSAGE_CHARS * ASCII_BITS)
    ciphertext_int = bits_to_int(ciphertext_bits)
    padded_plaintext_int = pow(ciphertext_int, private_key, n)

    # If the message wasn't padded, we'll detect that here.
    padded_plaintext_bits = pad_bits(convert_to_bits(padded_plaintext_int),
                                     len(ciphertext_bits))
    plaintext_string = bits_to_string(padded_plaintext_bits).strip('\x00')
    if is_valid_message(plaintext_string):
        return plaintext_string
    else:
        return remove_oaep_from_plaintext(padded_plaintext_int, n)
Example #8
0
def decrypt_by_public_key_root(public_key, n, ciphertext):
    ciphertext_bits = string_to_bits(ciphertext)
    ciphertext_int = bits_to_int(ciphertext_bits)
    
    PUBLIC_KEY_ROOT_ATTEMPTS = 10
    for i in range(PUBLIC_KEY_ROOT_ATTEMPTS):
        plaintext_root_result = gmpy2.iroot(gmpy2.mpz(ciphertext_int + i * n), public_key)
        if plaintext_root_result[1]:
            plaintext_int = int(plaintext_root_result[0])
            assert pow(plaintext_int, public_key) == ciphertext_int + i * n              
            print("Found integer root of message")
                
            plaintext_bits = pad_bits(convert_to_bits(plaintext_int), MESSAGE_CHARS * ASCII_BITS)
            plaintext_string = bits_to_string(plaintext_bits).strip('\x00')

            assert is_valid_message(plaintext_string)
            return plaintext_string
        else:
            print("Root result is non-integer")

    print("Unable to decrypt by taking private key root")
    return None
Example #9
0
def decrypt_by_public_key_root(public_key, n, ciphertext):
    ciphertext_bits = string_to_bits(ciphertext)
    ciphertext_int = bits_to_int(ciphertext_bits)

    PUBLIC_KEY_ROOT_ATTEMPTS = 10
    for i in range(PUBLIC_KEY_ROOT_ATTEMPTS):
        plaintext_root_result = gmpy2.iroot(gmpy2.mpz(ciphertext_int + i * n),
                                            public_key)
        if plaintext_root_result[1]:
            plaintext_int = int(plaintext_root_result[0])
            assert pow(plaintext_int, public_key) == ciphertext_int + i * n
            print("Found integer root of message")

            plaintext_bits = pad_bits(convert_to_bits(plaintext_int),
                                      MESSAGE_CHARS * ASCII_BITS)
            plaintext_string = bits_to_string(plaintext_bits).strip('\x00')

            assert is_valid_message(plaintext_string)
            return plaintext_string
        else:
            print("Root result is non-integer")

    print("Unable to decrypt by taking private key root")
    return None
Example #10
0
def create_bill_message(i, bill_amount, nonce):
    bill = create_bill(i, bill_amount)

    bill_int = bits_to_int(string_to_bits(bill))
    t = blind_msg(bill_int, nonce, BANK_PUBLIC_KEY[0], BANK_PUBLIC_KEY[1])
    return t
Example #11
0
def run_mitm_session(first, second):
    """
    Run a message exchange between the specified parties, but
    perform a MITM attack using a known private key for the
    exchange with each in order to snoop on the contents
    of the messages.
    """
    first_initialization_response = initialize(first[0])
    first_session_token = first_initialization_response['token']
    
    second_initialization_response = initialize(second[0])
    second_session_token = second_initialization_response['token']
    
    pg = get_pg()
    p = int(pg['p'], 16)
    g = int(pg['g'], 16)
    
    eve_key_response_int = pow(g, X_EVE, p)
    eve_key_response = hex(eve_key_response_int)[2:] # chop off the "0x"
    
    first_key_received_response = send_key(first[0], first_session_token,
            eve_key_response, second[1])
    second_key_received_response = send_key(second[0], second_session_token,
            eve_key_response, first[1])
    
    (first_ctr_key, first_ctr_nonce) = get_ctr_info(X_EVE, int(first_initialization_response['public'], 16))
    (second_ctr_key, second_ctr_nonce) = get_ctr_info(X_EVE, int(second_initialization_response['public'], 16))
    
    first_person_message = receive_msg(first[0], first_session_token)
    
    first_person_decrypted_message = counter_mode_encrypt(first_person_message['msg'], first_ctr_key, first_person_message['iv'], first_ctr_nonce)
    first_person_decrypted_message_str = bits_to_string(first_person_decrypted_message)
    first_person_decrypted_message_hex = hex(bits_to_int(first_person_decrypted_message))[2:]

    test_encrypted_message_bits = counter_mode_encrypt(first_person_decrypted_message_hex, first_ctr_key, first_person_message['iv'], first_ctr_nonce)
    test_encrypted_message_str = hex(bits_to_int(test_encrypted_message_bits))[2:]
    assert test_encrypted_message_str == first_person_message['msg']    

    # Set up the message to be sent through the MITM session with second person
    first_re_encrypted_message_bits = counter_mode_encrypt(first_person_decrypted_message_hex, second_ctr_key, first_person_message['iv'], second_ctr_nonce)
    first_re_encrypted_message_str = hex(bits_to_int(first_re_encrypted_message_bits))[2:]
    
    response = send_msg(second[0], second_session_token,
            first_person_message['msg'], first_person_message['iv'])
    
    recipient, sender = first, second
    recipient_session_token, sender_session_token = first_session_token, second_session_token
    recipient_ctr_key, sender_ctr_key = first_ctr_key, second_ctr_key
    recipient_ctr_nonce, sender_ctr_nonce = first_ctr_nonce, second_ctr_nonce
    
    while 'reply' in response and 'iv' in response['reply'] and len(response['reply']['iv']) > 0:    

        decrypted_response = counter_mode_encrypt(response['reply']['msg'],
                sender_ctr_key, response['reply']['iv'], sender_ctr_nonce)
        decrypted_response_str = bits_to_string(decrypted_response)
        print(sender[1], "decrypted_response_str", decrypted_response_str)
    
        response = send_msg(recipient[0], recipient_session_token,
                response['reply']['msg'], response['reply']['iv'])
        
        # Switch places
        recipient, sender = sender, recipient
        recipient_session_token, sender_session_token = sender_session_token, recipient_session_token
        recipient_ctr_key, sender_ctr_key = sender_ctr_key, recipient_ctr_key
        recipient_ctr_nonce, sender_ctr_nonce = sender_ctr_nonce, recipient_ctr_nonce
Example #12
0
# http://forums.udacity.com/cs387-april2012/questions/2814/hw4-6-challenge-question-discussion
#
# If you want to use functions from unit4_util, make sure to set the ASCII_BITS = 8
# import unit4_util
# unit4_util.ASCII_BITS = 8
#
# unit4_util code: http://pastebin.com/Te2AmDre

from unit4_util import bits_to_int, string_to_bits, bits_to_string, convert_to_bits, pad_bits


################
e0 = 65537
n0 = 116436872704204817262873499608558046190724591466716177557829773662807162485791977636521167560986434993048860346504247233074117974671540999410485959711510256117299326339754889488213509449940603119123994148576130959569697235313003024809821145961963221161561975123663333322412762102191502543834949106445222007561
cipher0 = "<\xad\xdd\xedg\x8b\x12\x0b\x00y\xa2\xf0\x86\xcbF\xf0\x8f\xb4~\xbd\x04\xd9\xac6iwxk\xcfi\xc4Z1p\\\x14\xa4rL\x9a#\x9f\xbf~\xec[\x8d\xfc(\x82\xc2s\xb9\x0e\xec(\xd9.}\xc5\xdf\xa8'`\xa5\xdb\x18\xf1Z\xff\x82xQJa\x11\x98/x&{\x0b\x17\xb9\xb1\x88\x8f\x85B\x7fH\xdbX\x9aV\x9a\xaf\x0fKc+\xf7?\xb8\xb4\x1fo\x0eeI\xa9\x90\x11\x83\xb8\xfdaMwM\xc7\xb48&-\xe8\xf1C"
c0 = bits_to_int(string_to_bits(cipher0))
m0 = ''#YOUR ANSWER HERE
################

################
e1 = 3
n1 = 131776503472993446247578652375782286463851826883886018427615607890323792437218636575447994626809806013420405963813337101556738852432247872506699457038044621191649758706817663135648397013226104530751563478671698441687437700125203966101608457556637550910814187779205610883544935666685906870199595346450733709263
cipher1 = '\x04\xacq#E/\xf4X\x126\xef\xc6\xb1\xfc\x10p*\x98P\xde\x089K\x16y0\xfa\xde\x9f\x05\x15+\xa3\x0f\xbc3\xd1t\xe7\x9a\x1b\x04m\xa1\x12\x96\x18Y\xf9\xc95\xce\x19 E\xfa\xe1\xb5\x8a\xd5\xf2\x99\xa6"<\xcb\x1a\xd0\xce=\x91\xfbw\t\xb5'
c1 = bits_to_int(string_to_bits(cipher1))
m1 = 'Chinese Remainder Theorem'#YOUR ANSWER HERE
################

################
e2 = 3
n2 = 65659232975830381768328338666607829001259240689809015666589078261348261561917417083788447204534665997091584936794919521220643455263371034991817572752104164283083678838816431044389236958346474896965382016943200300407371205608596328649170408446414718769422147103617311701247139971805834487439320773304455320217
cipher2 = '\x04\xe97r\x13\x99\xf7\x80m\x19\xe3f\x1a\x92]u!\x17\xdf\xa8\xfd\xd4\xd0\xbea\xe8\x1f\xefc\xd6\xc7\xbf\xce\xa4q\xfe\xa4S\xff\xaf\x1aX\xc13g\xeb\x12\xadw\x17T\x05\x1c\x8e\xd8\xea\x1bkc\xd3\xfctQt\x8e\xf6d\x1a\x98\xbc}\x08\x1d%\xc7\xd2K\xb4\xa8\x96\xcf\x98D\x8a\xbd\xa7\xd2\xcc\x861$\xd1\x1b\xdd\xa0h\x83\xdan\xcbm\xa4\xf9\xef\x96\x12\x9c|\xc9\xd7\t\x9b\x0f:\x9e\xe0\xa1\xb2\t\x8b\x9d\x18\x07\x8e]\x8c\x13\xa2'
Example #13
0
def run_mitm_session(first, second):
    """
    Run a message exchange between the specified parties, but
    perform a MITM attack using a known private key for the
    exchange with each in order to snoop on the contents
    of the messages.
    """
    first_initialization_response = initialize(first[0])
    first_session_token = first_initialization_response['token']

    second_initialization_response = initialize(second[0])
    second_session_token = second_initialization_response['token']

    pg = get_pg()
    p = int(pg['p'], 16)
    g = int(pg['g'], 16)

    eve_key_response_int = pow(g, X_EVE, p)
    eve_key_response = hex(eve_key_response_int)[2:]  # chop off the "0x"

    first_key_received_response = send_key(first[0], first_session_token,
                                           eve_key_response, second[1])
    second_key_received_response = send_key(second[0], second_session_token,
                                            eve_key_response, first[1])

    (first_ctr_key, first_ctr_nonce) = get_ctr_info(
        X_EVE, int(first_initialization_response['public'], 16))
    (second_ctr_key, second_ctr_nonce) = get_ctr_info(
        X_EVE, int(second_initialization_response['public'], 16))

    first_person_message = receive_msg(first[0], first_session_token)

    first_person_decrypted_message = counter_mode_encrypt(
        first_person_message['msg'], first_ctr_key, first_person_message['iv'],
        first_ctr_nonce)
    first_person_decrypted_message_str = bits_to_string(
        first_person_decrypted_message)
    first_person_decrypted_message_hex = hex(
        bits_to_int(first_person_decrypted_message))[2:]

    test_encrypted_message_bits = counter_mode_encrypt(
        first_person_decrypted_message_hex, first_ctr_key,
        first_person_message['iv'], first_ctr_nonce)
    test_encrypted_message_str = hex(
        bits_to_int(test_encrypted_message_bits))[2:]
    assert test_encrypted_message_str == first_person_message['msg']

    # Set up the message to be sent through the MITM session with second person
    first_re_encrypted_message_bits = counter_mode_encrypt(
        first_person_decrypted_message_hex, second_ctr_key,
        first_person_message['iv'], second_ctr_nonce)
    first_re_encrypted_message_str = hex(
        bits_to_int(first_re_encrypted_message_bits))[2:]

    response = send_msg(second[0], second_session_token,
                        first_person_message['msg'],
                        first_person_message['iv'])

    recipient, sender = first, second
    recipient_session_token, sender_session_token = first_session_token, second_session_token
    recipient_ctr_key, sender_ctr_key = first_ctr_key, second_ctr_key
    recipient_ctr_nonce, sender_ctr_nonce = first_ctr_nonce, second_ctr_nonce

    while 'reply' in response and 'iv' in response['reply'] and len(
            response['reply']['iv']) > 0:

        decrypted_response = counter_mode_encrypt(response['reply']['msg'],
                                                  sender_ctr_key,
                                                  response['reply']['iv'],
                                                  sender_ctr_nonce)
        decrypted_response_str = bits_to_string(decrypted_response)
        print(sender[1], "decrypted_response_str", decrypted_response_str)

        response = send_msg(recipient[0], recipient_session_token,
                            response['reply']['msg'], response['reply']['iv'])

        # Switch places
        recipient, sender = sender, recipient
        recipient_session_token, sender_session_token = sender_session_token, recipient_session_token
        recipient_ctr_key, sender_ctr_key = sender_ctr_key, recipient_ctr_key
        recipient_ctr_nonce, sender_ctr_nonce = sender_ctr_nonce, recipient_ctr_nonce
Example #14
0
def encrypt(message, n, public_key, nonce, g, h):
    oaep = oaep_pad(message, nonce, g, h)
    m_int = bits_to_int(oaep)
    return convert_to_bits(pow(m_int, public_key, n))
Example #15
0
def create_bill_message(i, bill_amount, nonce):
    bill = create_bill(i, bill_amount)

    bill_int = bits_to_int(string_to_bits(bill))
    t = blind_msg(bill_int, nonce, BANK_PUBLIC_KEY[0], BANK_PUBLIC_KEY[1])
    return t