Exemplo n.º 1
0
def SRPSetup(sock, email, password):
    g = 2
    k = 3
    N = int(
        'ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e340'
        '4ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f40'
        '6b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8f'
        'd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff',
        16)

    sock.send(email.encode() + b'\n')

    a = random.randint(0, 10000)
    A = dh.modexp(g, a, N)

    message = (str(A) + '\n').encode()
    sock.send(message)

    salt = ReadUntilNewline(sock)
    B = ReadUntilNewline(sock)
    u = ReadUntilNewline(sock)

    sha = hashlib.sha256()
    sha.update(salt)
    sha.update(password.encode())
    x = int(sha.hexdigest(), 16)

    exp = (a + int(u) * x)
    S = dh.modexp(int(B), exp, N)

    sha = hashlib.sha256()
    sha.update(str(S).encode())
    K = sha.hexdigest()

    return K, salt
Exemplo n.º 2
0
def SRPSetup(sock, email, password):
	g = 2
	k = 3
	N = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e340'
			'4ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f40'
			'6b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8f'
			'd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff', 16)

	sock.send(email.encode() + b'\n')

	a = random.randint(0, 10000)
	A = dh.modexp(g, a, N)

	message = (str(A) + '\n').encode()
	sock.send(message)

	salt = ReadUntilNewline(sock)
	B = ReadUntilNewline(sock)
	u = ReadUntilNewline(sock)

	sha = hashlib.sha256()
	sha.update(salt)
	sha.update(password.encode())
	x = int(sha.hexdigest(), 16)

	exp = (a + int(u) * x)
	S = dh.modexp(int(B), exp, N)

	sha = hashlib.sha256()
	sha.update(str(S).encode())
	K = sha.hexdigest()

	return K, salt
Exemplo n.º 3
0
def SRPSetup(sock, email, password, isClientGood):
	g = 2
	k = 3
	N = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e340'
		    '4ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f40'
		    '6b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8f'
		    'd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff', 16)

	sock.send(email.encode() + b'\n')

	a = random.randint(0, 10000)

	if isClientGood:
		A = dh.modexp(g, a, N)
	else:
		# Sending this means that S = 0 server-side, since
		# A is the base of the modexp computing S, so all the
		# other parameters get ignored.
		# The other tweaking proposed, A = N or A = kN, have the
		# exact same effect, since you compute S = (A ** x) % A
		# which is equal to 0 no matter what 'x' is.
		A = 0

	message = (str(A) + '\n').encode()
	sock.send(message)

	salt = ReadUntilNewline(sock)
	B = ReadUntilNewline(sock)

	sha = hashlib.sha256()
	sha.update(str(A).encode())
	sha.update(B)
	u = int(sha.hexdigest(), 16)

	sha = hashlib.sha256()
	sha.update(salt)
	sha.update(password.encode())
	x = int(sha.hexdigest(), 16)

	if isClientGood:
		exp = (a + u * x)
		base = (int(B) - k * dh.modexp(g, x, N))
		S = dh.modexp(base, exp, N)
	else:
		# If we have been bad, we know the server has computed S = 0,
		# so we do the same on our side. We could also avoid computing
		# a bunch of other parameters before (namely, x and u).
		# At this point the secret is independent of which password
		# we send to the server, so we can send an empty one and still
		# be accepted as good users.
		S = 0

	sha = hashlib.sha256()
	sha.update(str(S).encode())
	K = sha.hexdigest()

	return K, salt
Exemplo n.º 4
0
def SRPSetup(clientsocket):
    g = 2
    k = 3
    # Use the same large prime we used before.
    N = int(
        'ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e340'
        '4ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f40'
        '6b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8f'
        'd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff',
        16)

    # Random salt.
    salt = random.randint(1, 100000)
    saltBytes = str(salt).encode()

    # Hash salt|password and convert the result to an integer, x. We do
    # this by simply taking the decimal equivalent of the hash.
    sha = hashlib.sha256()
    sha.update(saltBytes)
    sha.update(PASSWORD)
    xhash = sha.hexdigest()

    x = int(xhash, 16)
    v = dh.modexp(g, x, N)

    # We don't actually make any use of the email in this exercise,
    # but in a real implementation we would associate the email with
    # the expected password, and/or do other verifications.
    email = ReadUntilNewline(clientsocket)
    A = ReadUntilNewline(clientsocket)

    b = random.randint(1, 10000)
    B = k * v + dh.modexp(g, b, N)

    clientsocket.send(saltBytes + b'\n')
    clientsocket.send(str(B).encode() + b'\n')

    sha = hashlib.sha256()
    sha.update(A)
    sha.update(str(B).encode())
    u = int(sha.hexdigest(), 16)

    S = dh.modexp((int(A) * dh.modexp(v, u, N)), b, N)

    sha = hashlib.sha256()
    sha.update(str(S).encode())
    K = sha.hexdigest()

    # Returns both K and saltBytes as byte strings. This helps later
    # since we hash them.
    return K.encode(), saltBytes
Exemplo n.º 5
0
def SRPSetup(clientsocket):
    g = 2
    k = 3
    N = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e340'
            '4ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f40'
            '6b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8f'
            'd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff', 16)

    # Random salt.
    salt = str(random.randint(1, 100000)).encode()

    # Hash salt|password and convert the result to an integer, x. We do
    # this by simply taking the decimal equivalent of the hash.
    sha = hashlib.sha256()
    sha.update(salt)
    sha.update(PASSWORD)
    xhash = sha.hexdigest()

    x = int(xhash, 16)
    v = dh.modexp(g, x, N)

    # We don't actually make any use of the email in this exercise,
    # but in a real implementation we would associate the email with
    # the expected password, and/or do other verifications.
    email = ReadUntilNewline(clientsocket)
    A = ReadUntilNewline(clientsocket)

    b = random.randint(1, 10000)
    B = dh.modexp(g, b, N)

    clientsocket.send(salt + b'\n')
    clientsocket.send(str(B).encode() + b'\n')

    u = random.getrandbits(128)
    clientsocket.send(str(u).encode() + b'\n')

    S = dh.modexp((int(A) * dh.modexp(v, u, N)), b, N)

    sha = hashlib.sha256()
    sha.update(str(S).encode())
    K = sha.hexdigest()

    # Returns both K and salt as byte strings. This is used for verification.
    return K.encode(), salt
Exemplo n.º 6
0
def DHExchangeClient(serverHost, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((serverHost, port))

    # Usual parameters as recommended by NIST.
    pHex = (
        'ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e340'
        '4ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f40'
        '6b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8f'
        'd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff'
    )
    p = int(pHex, 16)
    g = 2

    a = random.randint(0, p - 1)
    A = dh.modexp(g, a, p)
    B = 0

    # Sends the message in the predefined format.
    message = 'BEGIN\n%s\n%s\n%s\nEND' % (str(p), str(g), str(A))
    sock.send(message.encode())

    # Gets a similar message back from the server. See the comments
    # on dh_server which has a similar loop.
    exchange = b''
    while b'D' not in exchange:
        exchange += sock.recv(100)

    exchange = exchange.decode()
    pieces = exchange.split('\n')

    B = int(pieces[1])
    secret = dh.modexp(B, a, p)

    print('My secret is', str(secret))
    VerifyKey(sock, secret)

    sock.close()
Exemplo n.º 7
0
def DHExchangeServer(clientsocket):
	A = 0
	p = 0
	g = 0
	exchange = b''

	# In this scenario, the DH exchange message has this form:
	# BEGIN
	# p
	# g
	# A
	# END
	# (including newlines). Therefore we keep reading 100 bytes
	# until we read D. We do not try and read the whole word
	# because it could fall across a boundary. However this only
	# works because the D is unique (p, g and A are integers).
	while b'D' not in exchange:
		exchange += clientsocket.recv(100)

	exchange = exchange.decode()
	pieces = exchange.split('\n')

	p = int(pieces[1])
	g = int(pieces[2])
	A = int(pieces[3])

	# Computes B and then the secret.
	b = random.randint(0, g - 1)
	B = dh.modexp(g, b, p)
	secret = dh.modexp(A, b, p)

	# Perform our side of the exchange, sending B to the client
	# with the same format.
	messageForClient = 'BEGIN\n%s\nEND' % str(B)
	clientsocket.send(messageForClient.encode())
	return secret
Exemplo n.º 8
0
def DHExchangeClient(serverHost, port):
	sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	sock.connect((serverHost, port))

	# Usual parameters as recommended by NIST.
	pHex = ('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e340'
		    '4ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f40'
		    '6b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8f'
		    'd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff')
	p = int(pHex, 16)
	g = 2

	a = random.randint(0, p - 1)
	A = dh.modexp(g, a, p)
	B = 0

	# Sends the message in the predefined format.
	message = 'BEGIN\n%s\n%s\n%s\nEND' % (str(p), str(g), str(A))
	sock.send(message.encode())

	# Gets a similar message back from the server. See the comments
	# on dh_server which has a similar loop.
	exchange = b''
	while b'D' not in exchange:
		exchange += sock.recv(100)

	exchange = exchange.decode()
	pieces = exchange.split('\n')

	B = int(pieces[1])
	secret = dh.modexp(B, a, p)

	print('My secret is', str(secret))
	VerifyKey(sock, secret)

	sock.close()
Exemplo n.º 9
0
def SRPDictionaryAttack(clientsocket):
    # The server needs to know at least g and N, basic parameters of the protocol,
    # for this to work, since they are both used several times below.
    g = 2
    #k = 3
    N = int(
        'ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e340'
        '4ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f40'
        '6b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8f'
        'd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff',
        16)

    # Random salt.
    salt = str(random.randint(1, 100000)).encode()

    # Do all the communication with the client upfront (minus the final "yes or
    # no" from the server) so we have the client's digest to compare with our
    # own.
    # Note that this is only possible because the computation of B does not
    # depend on the password digest itself.
    email = ReadUntilNewline(clientsocket)
    A = ReadUntilNewline(clientsocket)

    b = random.randint(1, 10000)
    # The challenge mentions to have an arbitrary value for B, but it has
    # to be this one or the S differs between client and server, and therefore
    # the password digests never match.
    # Anyway B depends on b which is random, and g and N which are protocol
    # parameters.
    B = dh.modexp(g, b, N)

    clientsocket.send(salt + b'\n')
    clientsocket.send(str(B).encode() + b'\n')

    u = random.getrandbits(128)
    clientsocket.send(str(u).encode() + b'\n')

    clientDigest = clientsocket.recv(64)

    # Most systems have /usr/share/dict/words, but here that contains bytes,
    # while this has the usual "one string per line" format.
    with open('/usr/share/dict/cracklib-small', 'r') as w:
        # For each password, compute the final digest and compare with the
        # digest received by the client. If we find a match we cracked the
        # password, otherwise the client was smart enough not to pick a
        # password that can be broken with a dictionary attack.
        for p in w.readlines():
            password = p.strip().encode()

            sha = hashlib.sha256()
            sha.update(salt)
            sha.update(password)
            xhash = sha.hexdigest()

            x = int(xhash, 16)
            v = dh.modexp(g, x, N)

            S = dh.modexp((int(A) * dh.modexp(v, u, N)), b, N)
            sha = hashlib.sha256()
            sha.update(str(S).encode())
            K = sha.hexdigest().encode()

            sha = hashlib.sha256()
            sha.update(salt)
            sha.update(K)
            digest = sha.hexdigest().encode()

            if clientDigest == digest:
                print('Cracked password:'******'Unable to crack password, sorry.')