예제 #1
0
def send_hmac_C(salt, B):
    xH = SHA256_hex(salt + password)
    x = int(xH, 16)
    u = int(SHA256_hex(util.int_to_bytes(A_C) + util.int_to_bytes(B)), 16)
    S = pow(B, a + u * x, N)
    K = SHA256(util.int_to_bytes(S))
    return HMAC.HMAC(SHA256, K, salt)
def search_for_pkcs_messages(i, c0, M, s):
    e, n = public_key
    if i == 1:  # 2.a
        s_new = ceil_div(n, 3 * B)
        while True:
            c = compute_homomorphic_c(c0, s_new)
            if pkcs_oracle(util.int_to_bytes(c)):
                return s_new
            s_new += 1
    elif len(M) > 1:  # 2.b
        s_new = s + 1
        while True:
            c = compute_homomorphic_c(c0, s_new)
            if pkcs_oracle(util.int_to_bytes(c)):
                return s_new
            s_new += 1
    else:  # 2.c
        (a, b) = M[0]
        r = 2 * ceil_div(b * s - 2 * B, n)
        while True:
            s_left = ceil_div(2 * B + r * n, b)
            s_right = ceil_div(3 * B + r * n, a)
            if s_left >= s_right:
                r += 1
                continue
            for s_new in range(s_left, s_right):
                c = compute_homomorphic_c(c0, s_new)
                if pkcs_oracle(util.int_to_bytes(c)):
                    return s_new
            r += 1
    # in theory, we should never get here
    return None
예제 #3
0
def dictionary_attack(hmac, salt, A, B):
    global b
    u = int(SHA256_hex(util.int_to_bytes(A) + util.int_to_bytes(B)), 16)
    with open('/usr/share/dict/words', 'r') as f:
        for word in f:
            for d in range(10):
                guess = (word.strip() + str(d)).encode('utf-8')
                xH = SHA256_hex(salt + guess)
                x = int(xH, 16)
                v = pow(g, x, N)
                S = pow((A * pow(v, u, N)), b, N)
                K = SHA256(util.int_to_bytes(S))
                if hmac == HMAC.HMAC(SHA256, K, salt):
                    return guess
def forge_signature(message, key):
    h = SHA.new(message).hexdigest()
    asn_prefix = '3021300906052b0e03021a05000414'
    desired_message = '01ff00' + asn_prefix + h + 'ff' * 80
    m = int(desired_message, 16)
    s = util.iroot(3, m)
    signature = util.int_to_bytes(s)
    return signature
예제 #5
0
def send_message_B(ciphertext, iv):
    global s_B, A_B, b, p
    s_B = pow(A_B, b, p)
    key = hashes.SHA1(util.int_to_bytes(s_B))
    key = util.get_ith_block(key, 0, BLOCK_SIZE)
    plaintext = util.cbc_decrypt(ciphertext, key, iv)
    assert plaintext == MESSAGE
    iv = util.random_byte_string(BLOCK_SIZE)
    return (util.cbc_encrypt(plaintext, key, iv), iv)
예제 #6
0
def send_message_A(B):
    global s_A, a, p, B_A
    B_A = B
    s_A = pow(B_A, a, p)
    msg = MESSAGE
    key = hashes.SHA1(util.int_to_bytes(s_A))
    key = util.get_ith_block(key, 0, BLOCK_SIZE)
    iv = util.random_byte_string(BLOCK_SIZE)
    return (util.cbc_encrypt(msg, key, iv), iv)
예제 #7
0
def md_hash(message, state_len = STATE_LEN, H = None):
  # initial state
  h = b''.join([util.int_to_bytes((37*i + 42) % 256) for i in range(state_len)])
  if not H:
    H = h
  M = util.padding(message, AES_BLOCK_SIZE)
  for i in range(len(M)//AES_BLOCK_SIZE):
    Mi = util.get_ith_block(M, i, AES_BLOCK_SIZE)
    H = util.ecb_encrypt(Mi, util.padding(H, AES_BLOCK_SIZE))[0:state_len]
  return binascii.hexlify(H)
예제 #8
0
def generate_many_collisions(rounds):
  h = b''.join([util.int_to_bytes((37*i + 42) % 256) for i in range(STATE_LEN)])
  colliding_messages = set()
  colliding_messages.add(b'')
  for i in range(rounds):
    new_set = set()
    m1, m2, h = find_block_collision(h)
    m1 = util.padding(m1, AES_BLOCK_SIZE)
    m2 = util.padding(m2, AES_BLOCK_SIZE)
    for m in colliding_messages:
      new_set.add(m + m1)
      new_set.add(m + m2)
    colliding_messages = new_set
  return colliding_messages
def recover_message(ciphertext):
    global public_key
    e, n = public_key
    c = int(binascii.hexlify(ciphertext), 16)
    x = pow(2, e, n)
    left = 0
    right = n - 1

    for i in range(1, KEY_SIZE + 1):
        y = pow(x, i, n)
        r = (c * y) % n
        b = return_parity(util.int_to_bytes(r))

        l = (left * pow(2, i - 1, n)) % n
        z = (n - 2 * l - 1) // pow(2, i)
        mid = left + z

        if b == 0:
            right = mid
        else:
            left = mid + 1

    m = left
    return util.int_to_bytes(m)
예제 #10
0
def broadcast_attack(c1, c2, c3, p1, p2, p3):
    _, n1 = p1
    _, n2 = p2
    _, n3 = p3

    c1 = int(binascii.hexlify(c1), 16)
    c2 = int(binascii.hexlify(c2), 16)
    c3 = int(binascii.hexlify(c3), 16)

    x1 = c1 * n2 * n3 * util.modinv(n2 * n3, n1)
    x2 = c2 * n3 * n1 * util.modinv(n3 * n1, n2)
    x3 = c3 * n1 * n2 * util.modinv(n1 * n2, n3)

    m_cubed = (x1 + x2 + x3) % (n1 * n2 * n3)
    m = util.iroot(3, m_cubed)
    return util.int_to_bytes(m)
def faulty_verifier(message, signature, key):
    n = key.n
    e = 3

    s = int(binascii.hexlify(signature), 16)
    m = util.int_to_bytes(pow(s, e, n))

    r = re.match(br'01(ff)+00', binascii.hexlify(m))
    if not r:
        return False
    asn = binascii.unhexlify(binascii.hexlify(m)[r.end():])
    try:
        sequence = asn1.DerSequence()
        sequence.decode(asn)
        assert len(sequence) == 2
        assert len(sequence[1]) == 20 + 2
        found_hash = sequence[1][2:]
    except (ValueError, IndexError) as e:
        return False

    expected_hash = SHA.new(message).digest()
    return expected_hash == found_hash
def recover_message(ciphertext):
    # Setup
    global B
    B = pow(2, 8 * (k - 2))

    # Step 1
    # Our plaintext is already PKCS1.5 padded, so the blinding
    # is not necessary
    c = int(binascii.hexlify(ciphertext), 16)
    s = 1
    M = [(2 * B, 3 * B - 1)]
    i = 1

    while True:
        # Step 2
        s = search_for_pkcs_messages(i, c, M, s)
        # Step 3
        M = update_interval(M, s)
        # Step 4
        if len(M) == 1 and M[0][0] == M[0][1]:
            plaintext = util.int_to_bytes(M[0][0])
            return pkcs_unpad(plaintext)
        i += 1
예제 #13
0
from utilities import util
import binascii

# Challenge 54

STATE_LEN = 4  # 32 bits
BLOCK_SIZE = 16  # 128 bits
LEN_ENC_SIZE = 8  # 64 bits

initial_state = b''.join(
    [util.int_to_bytes((37 * i + 42) % 256) for i in range(STATE_LEN)])

# Notes
#  - Hash functions are sometimes used as proof of a secret prediction. A
#    naive forgery would require a second pre-image attack.
#  - We (again) exploit the difference in difficulty between collisions
#    and second pre-images for this attack. We also exploit the ability
#    to precompute a lot of collisions.
#  - We create a funnel-like structure to hash many possible initial states
#    into one single final state
#  - The dummy hash function we use here has the following properties:
#     * 32 bit state
#     * 128 bit block
#     * 64 bit length encoding
#    Finding a second pre-image requires 2^32 operations (considered
#    infeasible in terms of programming competitions), but finding a
#    collision requires only 2^16 operations, which is comparatively trivial.
#  - If we have enough leaves in our funnel (say, 2^10 = 1024), finding
#    a collision takes only 2^22 time.
#  - We'll use the following list of spoilers below as our 'prediction'.
예제 #14
0
파일: RSA.py 프로젝트: johndpope/cryptopals
def encrypt(m, public_key):
    m_num = int(binascii.hexlify(m), 16)
    c_num = encrypt_num(m_num, public_key)
    return util.int_to_bytes(c_num)
예제 #15
0
def verify_hmac_S(hmac):
    u = int(SHA256_hex(util.int_to_bytes(A_S) + util.int_to_bytes(B)), 16)
    S = pow((A_S * pow(v, u, N)), b, N)
    K = SHA256(util.int_to_bytes(S))
    return hmac == HMAC.HMAC(SHA256, K, salt)
예제 #16
0
파일: RSA.py 프로젝트: johndpope/cryptopals
def decrypt(c, private_key):
    c_num = int(binascii.hexlify(c), 16)
    m_num = decrypt_num(c_num, private_key)
    return util.int_to_bytes(m_num)
예제 #17
0
    B_B = dh.send_params_B(p, g, A_A)
    (ciphertext, iv) = dh.send_message_A(B_B)
    (ciphertext, iv) = dh.send_message_B(ciphertext, iv)
    print('Successfully executed DH Protocol')

    # Simulate MITM Attack on DH Protocol
    # by messing with the 'g' parameter

    # g = 1
    (p, g, A_A) = dh.send_params_A()
    B_B = dh.send_params_B(p, 1, 1)
    (ciphertext, iv) = dh.send_message_A(B_B)
    (_, _) = dh.send_message_B(ciphertext, iv)

    s = 1
    key = hashes.SHA1(util.int_to_bytes(s))
    key = util.get_ith_block(key, 0, dh.BLOCK_SIZE)
    plaintext = util.cbc_decrypt(ciphertext, key, iv)
    assert plaintext == dh.MESSAGE

    # g = p
    (p, g, A_A) = dh.send_params_A()
    B_B = dh.send_params_B(p, p, 0)
    (ciphertext, iv) = dh.send_message_A(B_B)
    (_, _) = dh.send_message_B(ciphertext, iv)

    s = 0
    key = hashes.SHA1(util.int_to_bytes(s))
    key = util.get_ith_block(key, 0, dh.BLOCK_SIZE)
    plaintext = util.cbc_decrypt(ciphertext, key, iv)
    assert plaintext == dh.MESSAGE
예제 #18
0
from utilities import util
import binascii

# Challenge 53

STATE_LEN = 4 # 32 bits
BLOCK_SIZE = 16 # 128 bits
LEN_ENC_SIZE = 8 # 64 bits

initial_state = b''.join([util.int_to_bytes((37*i + 42) % 256) for i in range(STATE_LEN)])

# Notes
#  - Modern hash functions include the length of the message (modulo some huge
#    value) in the padding. This makes some conventional attacks a little
#    trickier.
#  - Collisions are much easier to find than second pre-images (birthday
#    paradox). Finding an expandable message requires many *collisions*.
#    Colliding with an intermediate state of a long message requires a
#    second pre-image of any of the intermediate states
#  - The dummy hash function we use here has the following properties:
#     * 32 bit state
#     * 128 bit block
#     * 64 bit length encoding
#    So, finding a second pre-image requires 2^32 operations (considered
#    infeasible in terms of programming competitions), but finding a
#    collision requires only 2^16 operations, which is comparatively trivial.
#  - If we have a long enough message, say 10000 blocks long, we can collide
#    with any of the intermediate blocks requiring only 2^32 / 10000 operations
#    which is feasible.
#  - We'll use the complete text of Arthur Conan Doyle's *The Hound of the
#    Baskervilles* as our long text. It's about 20000 blocks long.
def send_hmac_M(salt, B):
    K = srp.SHA256(util.int_to_bytes(0))
    return HMAC.HMAC(srp.SHA256, K, salt)