Example #1
0
def srp_connect(addr, name, password):
    print 'Connecting to %s:%d...' % addr
    con = socket()
    con.connect(addr)

    #C -> S name, A=g^a
    a, A = gen_key_pair()
    send_len_payload(con, name)
    send_bigint(con, A)

    #S -> C salt, B = kv + g^b
    salt = recv_len_payload(con)
    B = recv_bigint(con)

    #compute u = H(A | B)
    u = _compute_u(A, B)
    x = _compute_x(salt, password)

    #S = (B - kg^x)^(a + ux) = (kv + g^b - kv)^(a + ux) = g^(b(a + ux))
    S = pow(B - k * pow(nist_g, x, nist_p), (a + u * x) % nist_p, nist_p)
    K = sha256sum(bigint_to_bytes(S))

    #C -> S
    send_len_payload(con, hmac_sha256(K, salt))

    ok = recv_len_payload(con)

    if ok != 'ok':
        print 'SRP failed. Server returned "%s"' % ok
        return None, None
    print 'Established shared key: ', K.encode('hex')
    return con, K
Example #2
0
def handle_srp_client(con, addr):
    #C -> S name, A=g^a
    name = recv_len_payload(con)

    if name not in users:
        send_len_payload(con, 'error: non existant account')
        con.close()
        return
    v, salt = users[name]

    A = recv_bigint(con)

    #S -> C salt, B=kv + g^b
    b = random.SystemRandom().randrange(nist_p)
    #B = k*v + g^b = kg^H(salt + password) + g^b
    B = (k * v + pow(nist_g, b, nist_p)) % nist_p

    send_len_payload(con, salt)
    send_bigint(con, B)

    #compute u = H(A | B)
    u = _compute_u(A, B)

    #S = (A v^u)^b = (g^a g^(ux))^b = (g^(a + ux))^b = g^(b(a + ux))
    S = pow(A * pow(v, u, nist_p), b, nist_p)
    K = sha256sum(bigint_to_bytes(S))

    #C -> S mac(K, salt)
    tag = recv_len_payload(con)

    if hmac_sha256(K, salt) != tag:
        print 'Invalid mac'
        send_len_payload(con, 'error: invalid mac')
        con.close()
        return

    send_len_payload(con, 'ok')
    print 'Established shared key: ', K.encode('hex')
    send_len_payload(con, 'success!!!')
    con.close()
Example #3
0
def check_signature(msg, sig, e, n, bit_length=1024):
    p = util.bigint_to_bytes(rsa.rsa_encrypt(sig, e, n))
    if len(p) > bit_length / 8: return False

    #pad to bit_length with leading 0 bytes
    if len(p) < bit_length / 8:
        p = '\x00' * (bit_length / 8 - len(p)) + p

    #check that s^e (mod n) starts with
    #00 01 FF FF ... FF 00  ASN.1  HASH
    #check for 00 01 FF
    if not p.startswith(prefix): return False
    pos = len(prefix)
    #move past the rest of the FFs
    while pos < len(p) and p[pos] == '\xff':
        pos += 1
    #check that there is enough space for 00 ASN.1 HASH
    if pos + len(pkcs_magic_bytes) + 20 > len(p): return False
    #check for 00 ASN.1
    if p[pos:pos + len(pkcs_magic_bytes)] != pkcs_magic_bytes:
        return False
    pos += len(pkcs_magic_bytes)
    #check that hash matches message
    return p[pos:pos + 20] == util.sha1sum(msg)
Example #4
0
def send_bigint(con, i):
    '''sends <length> <bigint>'''
    return send_len_payload(con, util.bigint_to_bytes(i))
Example #5
0
        if rsa_blob in self._seen:
            return
        return rsa.rsa_decrypt(rsa_blob, self._d, self._n)

    def get_ct(self):
        pt = "%d something" % int(time.time())
        ct = rsa.rsa_encrypt(pt, self._e, self._n)
        self._seen.add(ct)
        return ct

    def get_public_key(self):
        return self._e, self._n


if __name__ == '__main__':
    oracle = Oracle()
    ct = oracle.get_ct()

    #cannot query oracle on ciphertexts it has already seen
    assert (oracle.query(ct) == None)

    e, n = oracle.get_public_key()

    #c' = s^e*c ==> p' = (s^e*c)^d = s*p
    s = 2
    ctp = (pow(s, e, n) * ct) % n

    ptp = oracle.query(ctp)
    pt = (ptp * number_theory.mod_inv(s, n)) % n
    print util.bigint_to_bytes(pt)
Example #6
0
    if verbose:
        print 'e, d = %d, %d' % (e, d)
    return d, e, n


def rsa_encrypt(m, e, n):
    if isinstance(m, basestring):
        m = util.bytes_to_bigint(m)
    return pow(m, e, n)


def rsa_decrypt(c, d, n):
    if isinstance(c, basestring):
        c = util.bytes_to_bigint(c)
    return pow(c, d, n)


#Don't wan't to wait for params to be generated? ==> use these
_sample_params = (
    111362286410211583669725041748624015357015789920103016229885764684530821371586941962831815326506479749001616409906800547275431285766694970292540991623633822700408019631094608796497093656659564366838349269038200838176792713390842709111079260436382859247229353043625367114615775993991276917586476130163934190371L,
    3,
    167043429615317375504587562622936023035523684880154524344828647026796232057380412944247722989759719623502424614860200820913146928650042455438811487435450759902502377024707831573474592372202008245491689999576946888508161524416942544195053500973486143761844643232694997008489565006093697359038427190720833724177L
)

if __name__ == '__main__':
    d, e, n = gen_key_pair(128, verbose=True)
    m = 'hello'  #message length must be < n
    c = rsa_encrypt(m, e, n)
    mp = rsa_decrypt(c, d, n)
    assert (util.bigint_to_bytes(mp) == m)
Example #7
0
def _compute_u(A, B):
    #compute u = H(A | B)
    return bytes_to_bigint(sha256sum(bigint_to_bytes(A) + bigint_to_bytes(B)))
Example #8
0
    #r = (sk - H(m))/x mod q
    #r == r'=> (sk - H(m))/x == (s'k - H(m'))/x mod q
    #=> k(s - s') = H(m) - H(m') mod q
    #=> K = (H(m) - H(m'))/(s - s') mod q
    sigs_by_r = {}
    for s, r, m in sigs:
        if r not in sigs_by_r:
            sigs_by_r[r] = (s, m)
            continue
        #same r ==> same k?
        if r in sigs_by_r:
            sp, mp = sigs_by_r[r]
            #find nonce
            k = ((m - mp) * number_theory.mod_inv(s - sp, q)) % q
            #find private key from nonce
            x = p43.recover_private_key(None, r, s, k, q, m)
            return x


if __name__ == '__main__':
    sigs = load()
    x = find_key([(s, r, m) for _, s, r, m in sigs])
    if x:
        print 'Private key =', x
        h_pk = util.sha1sum(
            util.bigint_to_bytes(x).encode('hex')).encode('hex')
        #print 'sha(x) =', h_pk
        assert (h_pk == 'ca8f6f7c66fa362d40760d135b763eb8527d3d52')
    else:
        print 'No repeated nonces found :('
Example #9
0
def padding_oracle(c, d, n, mod_len):
    '''checks if PKCS #1v1.5 padding is of decryption is correct'''
    p = util.bigint_to_bytes(rsa.rsa_decrypt(c, d, n))
    #pad start with 0s so it has same length as modulus
    p = '\x00' * (mod_len - len(p)) + p
    return pkcs1.pkcs1_unpad(p, mod_len) != None
Example #10
0
                if padding_oracle((pow(s, e, n) * c) % n):
                    found = True
                    break
                s += 1
            r += 1
        a, b = _step3([(a, b)], B, n, s)[0]
    return b


if __name__ == '__main__':
    #don't want to have to wait for key generation each time
    #256 bit key
    #d, e, n = (37255313119928308596958693738000904270148055374803475499902820648455212368979L, 3, 55882969679892462895438040607001356405695530651745489982532299779733176320093L)
    d, e, n = rsa._sample_params

    m = 'Hello Adrian.'
    mod_len = pkcs1.num_bytes(n)
    B = 1 << (8 * mod_len - 16)

    M = util.bytes_to_bigint(pkcs1.pkcs1_pad(m, mod_len))

    c = rsa.rsa_encrypt(M, e, n)

    p = decrypt(c, e, n, lambda c: fast_oracle(c, d, n, 2 * B, 3 * B))
    p = util.bigint_to_bytes(p)
    #pad start with 0s so it has same length as modulus
    p = '\x00' * (mod_len - len(p)) + p
    p = pkcs1.pkcs1_unpad(p, mod_len)
    print p
    assert (p == m)
Example #11
0
			# 
			# ==> 2^(i + 1)*m in [n*lower_{i + 1}, n*(lower_{i + 1} + 1)]
			# ==> m in [n*lower_{i + 1}/2^(i + 1), n*upper_{i + 1}/2^(i + 1)]
			# Note: invariant 3 still holds
			lower <<= 1
		else:
			# 2^(i + 1)*m  - 2n*lower in [n, 2n]
			# ==> 2^(i + 1)*m in [n*(2*lower + 1), n*(2*lower + 2)]
			# ==> 2^(i + 1)*m in [n*(2*lower + 1), n*2*upper]
			# upper_{i + 1} = 2*upper
			# lower_{i + 1} = 2*upper - 1
			# Note: invariant 2 still holds
			# 
			# ==> 2^(i + 1)*m in [n*lower_{i + 1}, n*upper_{i + 1}]
			# ==> m in [n*lower_{i + 1}/2^(i + 1), n*upper_{i + 1}/2^(i + 1)]
			# Note: invariant 3 still holds
			#(lower + 1) * 2 - 1 = 2*lower + 1
			lower = (lower << 1) + 1
		i = i + 1
	# 2^i >= n ==>
	#The interval [n*lower/2^i, n*upper/2^i] has width <= 1
	#integer division by 2^i rounds down ==> use upper bound to find m
	return ((lower + 1)*n) >> i

if __name__ == '__main__':
	pt = base64.b64decode('VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ==')
	d, e, n = rsa._sample_params
	ct = rsa.rsa_encrypt(pt, e, n)
	
	print util.bigint_to_bytes(decrypt(ct, e, n, lambda ct: oracle(ct, d, n)))
Example #12
0
import number_theory
import rsa
import util

#see: https://people.freebsd.org/~lstewart/references/apple_tr_kt32_cuberoot.pdf
#for computing cube roots

if __name__ == '__main__':
    #get 3 RSA keys all with e = 3
    _, e1, n1 = rsa.gen_key_pair(64)
    _, e2, n2 = rsa.gen_key_pair(64)
    _, e3, n3 = rsa.gen_key_pair(64)
    assert ({e1, e2, e3} == {3})

    #if same message is encrypted with all keys
    m = "hello"
    c1 = rsa.rsa_encrypt(m, 3, n1)
    c2 = rsa.rsa_encrypt(m, 3, n2)
    c3 = rsa.rsa_encrypt(m, 3, n3)

    #then
    #c_i = m^3 (mod n_i)
    #So by CTR we can find m^3  (mod n_1*n_2*n_3)
    m_cubed = number_theory.crt([c1, c2, c3], [n1, n2, n3])

    #m < n_i ==> m^3 < n_1*n_2*n_3
    #==> we can find m by taking a normal cube root
    mp = util.bigint_to_bytes(number_theory.ith_root(m_cubed, 3))
    assert (m == mp)
    print 'Recovered message:', mp