Example #1
0
def LogoutSequence(clientInfo):
    global dh_aes_key
    global serverpubkey
    global serverIP

    # Message format for logout {username,K{logout},N1}serverpublickey
    # Encrypt the logout command using the DH shared key
    iv = os.urandom(LengthIV)
    logoutinfo = AESEncrypt('logout', dh_aes_key, iv)

    # Compute the nonce
    N1 = os.urandom(LengthN)
    exitinfo = bytes(N1) + bytes(clientInfo + ',' + logoutinfo)

    # Encrypt using aes key
    sym_key = keygen()
    ciphertext = AESEncrypt(exitinfo, sym_key, iv)

    # Encrypt the symmetric key with rsa public key
    cipher_sym_key = RSAEncrypt(sym_key, serverpubkey)

    exit_msg = bytes(0x01) + bytes(iv) + bytes(cipher_sym_key) + bytes(
        ciphertext)
    server_socket.sendto(exit_msg, (serverIP, int(serverPort)))
    (Dport, addr) = server_socket.recvfrom(4096)
    (dataRecv, addr) = server_socket.recvfrom(4096)

    offset = InitOffset
    newiv = dataRecv[offset:offset + LengthIV]
    offset += LengthIV
    cipher = dataRecv[offset:len(dataRecv)]

    text = AESDecrypt(dh_aes_key, newiv, cipher)
    NONCE1 = text[0:LengthN]
    NONCE2 = text[LengthN:len(text)]
    try:
        if NONCE1 == N1:
            iv1 = os.urandom(LengthIV)
            challenge_response = bytes(NONCE2) + bytes(clientInfo)
            # Encrypt using aes key
            sym_key1 = keygen()
            ciphertext1 = AESEncrypt(challenge_response, sym_key1, iv1)

            # Encrypt the symmetric key with rsa public key
            cipher_sym_key1 = RSAEncrypt(sym_key1, serverpubkey)
            exitmsg = bytes(iv1) + bytes(cipher_sym_key1) + bytes(ciphertext1)
            server_socket.sendto(exitmsg, (serverIP, int(Dport)))
    except:
        print('Failed authentication')
        raise
    finally:
        exit(0)
    pass
Example #2
0
def LogoutSequence(clientInfo):
   global dh_aes_key
   global serverpubkey
   global serverIP

   # Message format for logout {username,K{logout},N1}serverpublickey
   # Encrypt the logout command using the DH shared key
   iv = os.urandom(LengthIV)
   logoutinfo = AESEncrypt('logout', dh_aes_key, iv)

   # Compute the nonce
   N1 = os.urandom(LengthN)
   exitinfo = bytes(N1) + bytes(clientInfo + ',' + logoutinfo)

   # Encrypt using aes key
   sym_key=keygen()
   ciphertext = AESEncrypt(exitinfo, sym_key, iv)

   # Encrypt the symmetric key with rsa public key
   cipher_sym_key = RSAEncrypt(sym_key, serverpubkey)

   exit_msg = bytes(0x01) + bytes(iv) + bytes(cipher_sym_key) + bytes(ciphertext)
   server_socket.sendto(exit_msg, (serverIP, int(serverPort))) 
   (Dport, addr) = server_socket.recvfrom(4096)
   (dataRecv, addr) = server_socket.recvfrom(4096)

   offset = InitOffset
   newiv = dataRecv[offset:offset+LengthIV]
   offset += LengthIV
   cipher = dataRecv[offset:len(dataRecv)]
   
   text = AESDecrypt(dh_aes_key, newiv, cipher)
   NONCE1 = text[0:LengthN]
   NONCE2 = text[LengthN:len(text)]
   try:
      if NONCE1 == N1:
         iv1 = os.urandom(LengthIV)
         challenge_response = bytes(NONCE2) + bytes(clientInfo)
         # Encrypt using aes key
         sym_key1=keygen()
         ciphertext1 = AESEncrypt(challenge_response, sym_key1, iv1)
  
         # Encrypt the symmetric key with rsa public key
         cipher_sym_key1 = RSAEncrypt(sym_key1, serverpubkey)
         exitmsg = bytes(iv1) + bytes(cipher_sym_key1) + bytes(ciphertext1)
         server_socket.sendto(exitmsg, (serverIP, int(Dport)))
   except:
       print('Failed authentication')
       raise
   finally:
       exit(0)
   pass
Example #3
0
def ListSequence(clientinfo):
    global dh_aes_key
    global serverpubkey
    global serverIP

    # Format of list command {Alice,K{list}} server-public-key
    # Encrypt the list command using the DH shared key
    N1 = os.urandom(LengthN)
    iv = os.urandom(LengthIV)
    listinfo = AESEncrypt('list', dh_aes_key, iv)

    list_msg = bytes(N1) + bytes(clientinfo + ',' + listinfo)
    # Encrypt username and list command using new aes key and then encrypt the aes key using server public key
    sym_key = keygen()
    encrypted_list = AESEncrypt(list_msg, sym_key, iv)

    cipher_sym_key = RSAEncrypt(sym_key, serverpubkey)
    send_list_msg = bytes(0x01) + bytes(iv) + bytes(cipher_sym_key) + bytes(
        encrypted_list)
    print('Sending list command')
    server_socket.sendto(send_list_msg, (serverIP, int(serverPort)))
    (Dport, addr) = server_socket.recvfrom(4096)

    # Receive list of users active on the server
    (dataRecv, addr) = server_socket.recvfrom(4096)
    offset = InitOffset
    iv1 = dataRecv[offset:offset + LengthIV]
    offset += LengthIV
    ciphernew = dataRecv[offset:len(dataRecv)]

    # Decrypt ciphernew
    text = AESDecrypt(dh_aes_key, iv1, ciphernew)
    print('List of Users currently active:')
    print str(bytes(text)).strip('')
Example #4
0
def ListSequence(clientinfo):
   global dh_aes_key
   global serverpubkey
   global serverIP

   # Format of list command {Alice,K{list}} server-public-key
   # Encrypt the list command using the DH shared key
   N1 = os.urandom(LengthN) 
   iv = os.urandom(LengthIV)	
   listinfo = AESEncrypt('list', dh_aes_key, iv)

   list_msg = bytes(N1) + bytes(clientinfo + ',' + listinfo)
   # Encrypt username and list command using new aes key and then encrypt the aes key using server public key
   sym_key = keygen()
   encrypted_list = AESEncrypt(list_msg, sym_key, iv)

   cipher_sym_key = RSAEncrypt(sym_key, serverpubkey)
   send_list_msg = bytes(0x01) + bytes(iv) + bytes(cipher_sym_key) + bytes(encrypted_list)
   print('Sending list command')
   server_socket.sendto(send_list_msg, (serverIP, int(serverPort)))
   (Dport, addr) = server_socket.recvfrom(4096)

   # Receive list of users active on the server 
   (dataRecv, addr) = server_socket.recvfrom(4096)
   offset = InitOffset
   iv1 = dataRecv[offset:offset+LengthIV]
   offset += LengthIV
   ciphernew = dataRecv[offset:len(dataRecv)]

   # Decrypt ciphernew
   text = AESDecrypt(dh_aes_key, iv1, ciphernew)
   print('List of Users currently active:')
   print str(bytes(text)).strip('')
Example #5
0
def MsgSendSequence(peername, msg):
    # Fetch user info from server
    global dh_aes_key
    global serverpubkey
    global serverIP
    global username

    dynamic_socket = None
    try:
        # Format of send command {Alice,K{send Bob}} server-public-key
        # Encrypt the list command using the DH shared key
        N1 = os.urandom(LengthN)
        iv = os.urandom(LengthIV)
        sendinfo = AESEncrypt('send ' + peername, dh_aes_key, iv)
        send_msg = bytes(N1) + bytes(username + ',' + str(sendinfo))

        # Encrypt username and list command using new aes key and then encrypt the aes key using server public key
        sym_key = keygen()
        encrypted_send = AESEncrypt(send_msg, sym_key, iv)

        cipher_sym_key = RSAEncrypt(sym_key, serverpubkey)
        send_msg = bytes(0x01) + bytes(iv) + bytes(cipher_sym_key) + bytes(
            encrypted_send)
        print('Sending send command')
        server_socket.sendto(send_msg, (serverIP, int(serverPort)))
        (Dport, addr) = server_socket.recvfrom(4096)

        # Receive peer info from the server
        (dataRecv, addr) = server_socket.recvfrom(4096)
        offset = InitOffset
        iv1 = dataRecv[offset:offset + LengthIV]
        offset += LengthIV
        ciphernew = dataRecv[offset:len(dataRecv)]

        # Decrypt ciphernew
        peerInfo = AESDecrypt(dh_aes_key, iv1, ciphernew)
        (peerCommKey, comm_private_key, dynamic_socket,
         D_addr) = AuthSequenceA(peerInfo)

        # Encrypt msg and send it to peer
        if (peerCommKey == None or comm_private_key == None):
            print "Sending msg failed"
        else:
            peerCommKey = serialization.load_pem_public_key(
                peerCommKey, backend=default_backend())
            comm_private_key = serialization.load_pem_private_key(
                comm_private_key, password=None, backend=default_backend())
            msg = encryptSendMsg(peerCommKey, comm_private_key, msg)
            dynamic_socket.sendto(msg, (D_addr[0], int(D_addr[1])))
        print "Message has been sent"
    except socket.timeout:
        print "Timeout... please try to re-send the command"
    except:
        print "Unexpected error:", sys.exc_info()[0]
    finally:
        if dynamic_socket != None:
            dynamic_socket.close()
        return
Example #6
0
def LoginSequence(dynamic_socket, addr, dataRecv):
    global user_DHkey
    global user_networkinfo
    global serverprivkey

    print 'LoginSequence'

    # msg format greeting_msg = bytes(0x00)  + bytes(iv) + bytes(cipher_key_sym) + bytes(ciphertext)
    cipher_key_sym = None
    ciphertext = None
    iv = None
    moduli = None

    offset = InitOffset  # Initial offset
    msg_type = dataRecv[offset]  # byte 0 contains the msg_type
    offset += LengthType
    iv = dataRecv[offset:offset + 16]  # 16 bytes of IV
    offset += LengthIV
    cipher_key_sym = dataRecv[offset:offset +
                              256]  # 256 bytes of the symmetric key
    offset += LengthKey
    ciphertext = dataRecv[offset:len(dataRecv)]  # The encrypted text

    # Load Private key of the server
    try:
        with open('serverprivkey.pem', 'rb') as f:
            serverprivkey = serialization.load_pem_private_key(
                f.read(), password=None, backend=default_backend())
    except:
        print("The file specified does not exist")
        sys.exit(2)

    # Decrypt key_sym with reciever's private key
    key_sym = RSADecrypt(cipher_key_sym, serverprivkey)

    # Decrypt the ciphertext using the key_sym and iv
    plaintext = AESDecrypt(key_sym, iv, ciphertext)
    N1 = bytes(plaintext)[0:32]
    plaintext = str(bytes(plaintext[32:len(bytes(plaintext))]))

    # Get data from plaintext
    split_data = plaintext.split(',')
    username = split_data[0]

    # Check if the user already exists
    try:
        if user_networkinfo[username] != [] or user_DHkey[username] != None:
            print "User has already logged in!"
            return
    except:
        print "User doesn't exist!"
        return

    # DH public key - 2^a mod p and rsa public key of the client
    client_dh_pub_key = split_data[1]
    client_rsa_pub_key = split_data[2]
    client_rsa_auth_key = serialization.load_pem_public_key(
        client_rsa_pub_key, backend=default_backend())

    u = DiffieHellman()
    b = str(u.privateKey)  # DH private key of the server
    dh_key_server = str(u.publicKey)  # DH public key of the server - 2^b mod p
    p = str(u.prime)  # p - prime number for DH
    moduli = user_moduli[username]  # 2^W mod p
    u.genHashSecretM(moduli, client_dh_pub_key)
    N2 = os.urandom(LengthN)
    msg = N1 + N2 + u.hashsecret + dh_key_server

    # Generate a aes key , iv and use it to encrypt the above msg
    aes_key = keygen()
    iv = os.urandom(LengthIV)
    ciphertext = AESEncrypt(msg, aes_key, iv)

    # Encrypt the symmetric key with client's rsa public key
    cipher_key_sym = RSAEncrypt(aes_key, client_rsa_auth_key)

    # Constant for GREETING is 0x00
    server_first_msg = bytes(0x00) + bytes(iv) + bytes(cipher_key_sym) + bytes(
        ciphertext)
    print 'Received Greeting from: ', username

    dynamic_socket.sendto(server_first_msg, (addr[0], int(addr[1])))

    (dataRecv, addr) = dynamic_socket.recvfrom(4096)
    print 'Verifying the hashes for ', username
    _N2 = dataRecv[0:LengthN]
    if _N2 != str(N2):
        print "Nonce N2 doesn't match"
        return

    u.genHashSecretM1(moduli, client_dh_pub_key)
    hash_recv = dataRecv[LengthN:len(dataRecv)]
    if hash_recv == u.hashsecret1:
        u.genKey(client_dh_pub_key)
    else:
        print 'Hashes does not match'
        return
    print 'Sending ACK to ', username

    sym_key_shared = aeskeygen(u.key)  # Generate AES key out of DH key
    iv = os.urandom(LengthIV)
    acknowledge = AESEncrypt('ACK', sym_key_shared,
                             iv)  # Encrypt the ACK with the symmetric key
    msg = bytes(iv) + bytes(acknowledge)
    dynamic_socket.sendto(
        msg, (addr[0], int(addr[1])))  # Send the ACK to the client

    print 'Waiting for Network Information of ', username
    (dataRecv, addr) = dynamic_socket.recvfrom(4096)
    offset = InitOffset
    new_iv = dataRecv[offset:offset + LengthIV]
    offset += LengthIV
    iv = dataRecv[offset:offset + LengthIV]
    offset += LengthIV
    cipher_key_new = dataRecv[offset:offset + LengthKey]
    offset += LengthKey
    nwciphertext = dataRecv[offset:len(dataRecv)]

    # Decrypt cipher_key_new with server's private key
    new_key_sym = RSADecrypt(cipher_key_new, serverprivkey)

    # Decrypt the nwciphertext using symmetric key decryption
    plaintext = AESDecrypt(new_key_sym, new_iv, nwciphertext)
    user = plaintext.split(',')[0]
    enc_nwinfo = plaintext[len(user) + 1:len(plaintext)]

    # Decrypt the nwinfo using DH key
    plaintext = AESDecrypt(sym_key_shared, iv, enc_nwinfo)
    ip_address = plaintext.split(',')[0]
    port_num = plaintext.split(',')[1]
    #print('Received common port and ip')

    # Register the client's network info along with the client rsa public key into user_networkinfo table
    user_networkinfo[username].append(ip_address)
    user_networkinfo[username].append(port_num)
    user_networkinfo[username].append(client_rsa_pub_key)

    # Register the DH shared key in the user_DHkey table
    user_DHkey[username] = sym_key_shared

    print('LOGIN SUCCESSFUL')
    print('------------------------------------------------------------------')
    pass
Example #7
0
def LoginSequence(username, password):
    global server_socket
    global serverIP
    global serverPort
    global client_socket
    global commonPort
    global dh_aes_key
    global serverpubkey
    global Dport
    global sender_private_key

    # Compute the nonce, a random no. of 32 bit
    nonce = os.urandom(LengthN)
    u = DiffieHellman()

    # modular prime and private key for DH exchange
    p = str(u.prime)
    a = str(u.privateKey)

    # public key g^a mod p
    dh_pub_key = str(u.publicKey)

    # Generate client rsa auth key pair
    try:
        sender_private_key = rsa.generate_private_key(
            public_exponent=65537, key_size=2048, backend=default_backend())
    except:
        print("The provided backend does not implement RSABackend")

    # Obtain the public key from the private key generated using RSA
    sender_public_key = sender_private_key.public_key()
    try:
        pem = sender_public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo)
    except:
        print("Serialization failed")

    # Get the server public key from the file
    try:
        with open('serverpubkey.pem', 'rb') as f1:
            serverpubkey = serialization.load_pem_public_key(
                f1.read(), backend=default_backend())
    except:
        print("The destination public key file is not present")
        sys.exit(2)

    msg = str(nonce) + username + ',' + str(dh_pub_key) + ',' + str(pem)

    # Encrypt using aes key
    key_sym = keygen()
    iv = os.urandom(16)
    ciphertext = AESEncrypt(msg, key_sym, iv)

    # Encrypt the symmetric key with rsa public key
    cipher_key_sym = serverpubkey.encrypt(
        key_sym,
        padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()),
                     algorithm=hashes.SHA1(),
                     label=None))

    # Constant for GREETING is 0x00
    greeting_msg = bytes(0x00) + bytes(iv) + bytes(cipher_key_sym) + bytes(
        ciphertext)
    server_socket.sendto(greeting_msg, (serverIP, int(serverPort)))
    (Dport, addr) = server_socket.recvfrom(4096)
    (dataRecv, addr) = server_socket.recvfrom(4096)

    # Use Dport to finish the rest of sequence server_socket.sendto(other_msg, (serverIP, Dport))
    # Server_first_msg = bytes(0x00)  + bytes(iv) + bytes(cipher_key_sym) + bytes(ciphertext)
    # msg = nonce + dh_key_server + ',' + u.hashsecret
    cipher_key_sym = None
    ciphertext = None
    iv = None
    offset = InitOffset
    msg_type = dataRecv[offset]
    offset += 1
    iv = dataRecv[offset:offset + LengthIV]
    offset += LengthIV
    cipher_key_sym = dataRecv[offset:offset + LengthKey]
    offset += LengthKey
    ciphertext = dataRecv[offset:len(dataRecv)]

    # Decrypt key_sym with sender's private key
    key_sym = RSADecrypt(cipher_key_sym, sender_private_key)

    # Decrypt the ciphertext using the key_sym and iv
    plaintext = AESDecrypt(key_sym, iv, ciphertext)
    plaintext = bytes(plaintext)
    offset = InitOffset
    nonce1 = plaintext[offset:offset + LengthN]
    offset += LengthN
    nonce2 = plaintext[offset:offset + LengthN]
    offset += LengthN

    if nonce1 != nonce:
        print "Nonce N1 doesn't match"
        exit(2)

    # Get data from plaintext
    hash_secret = plaintext[offset:offset + LengthN]
    offset += LengthN
    dh_key_server_public = plaintext[offset:len(plaintext)]

    # Generate hash secret
    W = hash32(password)
    u.genHashSecret(W, dh_key_server_public)

    if hash_secret == u.hashsecret:
        # Generate DH shared key
        u.genKey(dh_key_server_public)
        u.genHashSecret1(W, dh_key_server_public)
        server_socket.sendto(
            str(nonce2) + u.hashsecret1, (serverIP, int(Dport)))
    else:
        print('Hashes do not match')
        sys.exit(2)

    (dataRecv, addr) = server_socket.recvfrom(4096)
    offset = InitOffset
    iv = dataRecv[offset:offset + LengthIV]
    offset += LengthIV
    ciphertext = dataRecv[offset:len(dataRecv)]
    dh_aes_key = aeskeygen(u.key)

    # Decrypt the ciphertext using the key_sym and iv
    plaintext = AESDecrypt(dh_aes_key, iv, ciphertext)
    msg = str(bytes(plaintext))
    print('Received ACK')

    networkinfo = client_socket.getsockname()[0] + ',' + str(
        client_socket.getsockname()[1])

    # Encrypt the network info using DH Key
    iv = os.urandom(LengthIV)
    nwinfo = AESEncrypt(networkinfo, dh_aes_key, iv)

    # Encrypt username and encrypted networkinfo using new aes key , and encrypt sym key using rsa server ublic key
    new_iv = os.urandom(LengthIV)
    new_sym_key = keygen()
    msg_nwinfo = username + ',' + bytes(nwinfo)
    encrypted_msg = AESEncrypt(msg_nwinfo, new_sym_key, new_iv)

    # Encrypt the symmetric key with rsa public key
    cipher_new_key = RSAEncrypt(new_sym_key, serverpubkey)

    info_msg = bytes(new_iv) + bytes(iv) + bytes(cipher_new_key) + bytes(
        encrypted_msg)
    print('Sending common port info and peer AuthKey')
    server_socket.sendto(info_msg, (serverIP, int(Dport)))
    pass
Example #8
0
def AuthSequenceB(dynamic_socket, peerAdd, init_msg):
    global server_socket
    global sender_private_key
    global dh_aes_key

    print "AuthSequenceB"

    # Decrypt peer's user name
    dataRecv = RSADecrypt(init_msg, sender_private_key)
    r2 = dataRecv[0:LengthN]
    peername = str(dataRecv[LengthN:len(dataRecv)])

    # Fetch peer's AuthKey
    N1 = os.urandom(LengthN)
    iv = os.urandom(LengthIV)
    sendinfo = AESEncrypt('send ' + peername, dh_aes_key, iv)
    send_msg = bytes(N1) + bytes(username + ',' + sendinfo)

    # Encrypt send_msg using new aes key and then encrypt the aes key using server public key
    sym_key = keygen()
    encrypted_send = AESEncrypt(send_msg, sym_key, iv)

    cipher_sym_key = RSAEncrypt(sym_key, serverpubkey)
    send_msg = bytes(0x01) + bytes(iv) + bytes(cipher_sym_key) + bytes(
        encrypted_send)
    print('Sending send command')
    server_socket.sendto(send_msg, (serverIP, int(serverPort)))

    (Dport, addr) = server_socket.recvfrom(4096)
    # Receive peer info from the server
    (dataRecv, addr) = server_socket.recvfrom(4096)
    offset = InitOffset
    iv1 = dataRecv[offset:offset + LengthIV]
    offset += LengthIV
    ciphernew = dataRecv[offset:len(dataRecv)]

    # Decrypt ciphernew
    peerInfo = AESDecrypt(dh_aes_key, iv1, ciphernew)
    peerAdd_s = peerInfo.split(',')[0]
    if peerAdd_s != peerAdd[0]:
        print "Peer doesn't match... maybe impersonated..."
        return

    peerRSAKey = peerInfo.split(',')[2]
    peerRSAKey = serialization.load_pem_public_key(peerRSAKey,
                                                   backend=default_backend())

    # Finish the authentication
    r1 = os.urandom(LengthN)
    r1_e = RSAEncrypt(r1, peerRSAKey)
    msg = bytes(r2) + bytes(r1_e)
    print "Send reply to peer: " + peerAdd[0] + " : " + str(peerAdd[1])
    dynamic_socket.sendto(msg, (peerAdd[0], int(peerAdd[1])))

    # Waiting for CommKey
    (dataRecv, addr) = dynamic_socket.recvfrom(4096)
    r1_d = dataRecv[InitOffset:LengthN]
    if r1_d != r1:
        print 'Verification failed'
        return
    peerRSACommKey = dataRecv[LengthN:len(dataRecv)]
    peerRSACommKey = decryptSendMsg(peerRSACommKey, sender_private_key,
                                    peerRSAKey)

    # Generate CommKey and send to peer
    try:
        comm_private_key = rsa.generate_private_key(public_exponent=65537,
                                                    key_size=2048,
                                                    backend=default_backend())
    except:
        print("The provided backend does not implement RSABackend")
        return None

    # Obtain the public key from the private key generated using RSA
    comm_public_key = comm_private_key.public_key()
    try:
        pem = comm_public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo)
        pem_s = comm_private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption())
    except:
        print("Serialization failed")
        return None
    key = serialization.load_pem_public_key(peerRSACommKey,
                                            backend=default_backend())
    pem_cipher = encryptSendMsg(key, sender_private_key, pem)
    dynamic_socket.sendto(pem_cipher, (peerAdd[0], int(peerAdd[1])))

    return (peername, pem_s, peerRSACommKey)
Example #9
0
def LoginSequence(username, password):
   global server_socket
   global serverIP
   global serverPort
   global client_socket
   global commonPort
   global dh_aes_key
   global serverpubkey
   global Dport
   global sender_private_key

   # Compute the nonce, a random no. of 32 bit
   nonce = os.urandom(LengthN)
   u = DiffieHellman()

   # modular prime and private key for DH exchange
   p = str(u.prime)
   a = str(u.privateKey)

   # public key g^a mod p
   dh_pub_key = str(u.publicKey)

   # Generate client rsa auth key pair
   try:
      sender_private_key = rsa.generate_private_key(
      public_exponent=65537,
      key_size=2048,
      backend=default_backend())
   except:
      print("The provided backend does not implement RSABackend")

   # Obtain the public key from the private key generated using RSA
   sender_public_key = sender_private_key.public_key()
   try:
      pem = sender_public_key.public_bytes(
           encoding=serialization.Encoding.PEM,
           format=serialization.PublicFormat.SubjectPublicKeyInfo)
   except:
      print("Serialization failed")

   # Get the server public key from the file
   try:
      with open('serverpubkey.pem', 'rb') as f1:
          serverpubkey = serialization.load_pem_public_key(f1.read(), backend=default_backend())
   except:
      print("The destination public key file is not present")
      sys.exit(2)

   msg = str(nonce) + username + ',' + str(dh_pub_key) + ',' + str(pem)
  
   # Encrypt using aes key
   key_sym=keygen()
   iv = os.urandom(16)
   ciphertext = AESEncrypt(msg, key_sym, iv)

   # Encrypt the symmetric key with rsa public key
   cipher_key_sym = serverpubkey.encrypt(key_sym, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA1()),algorithm=hashes.SHA1(),label=None))
   
   # Constant for GREETING is 0x00
   greeting_msg = bytes(0x00)  + bytes(iv) + bytes(cipher_key_sym) + bytes(ciphertext)
   server_socket.sendto(greeting_msg, (serverIP, int(serverPort)))
   (Dport, addr) = server_socket.recvfrom(4096)
   (dataRecv, addr) = server_socket.recvfrom(4096)
   
   # Use Dport to finish the rest of sequence server_socket.sendto(other_msg, (serverIP, Dport))
   # Server_first_msg = bytes(0x00)  + bytes(iv) + bytes(cipher_key_sym) + bytes(ciphertext)
   # msg = nonce + dh_key_server + ',' + u.hashsecret
   cipher_key_sym = None
   ciphertext = None
   iv = None
   offset = InitOffset
   msg_type = dataRecv[offset]
   offset += 1
   iv = dataRecv[offset:offset+LengthIV]
   offset += LengthIV
   cipher_key_sym = dataRecv[offset:offset+LengthKey]
   offset += LengthKey
   ciphertext = dataRecv[offset:len(dataRecv)]

   # Decrypt key_sym with sender's private key
   key_sym = RSADecrypt(cipher_key_sym, sender_private_key)

   # Decrypt the ciphertext using the key_sym and iv
   plaintext = AESDecrypt(key_sym, iv, ciphertext)
   plaintext = bytes(plaintext)
   offset = InitOffset
   nonce1 = plaintext[offset:offset+LengthN]
   offset += LengthN
   nonce2 = plaintext[offset:offset+LengthN]
   offset += LengthN

   if nonce1 != nonce:
      print "Nonce N1 doesn't match"
      exit(2)

   # Get data from plaintext
   hash_secret = plaintext[offset:offset+LengthN]
   offset += LengthN
   dh_key_server_public = plaintext[offset:len(plaintext)]
   
   # Generate hash secret
   W = hash32(password)
   u.genHashSecret(W, dh_key_server_public)
  
   if hash_secret == u.hashsecret:
      # Generate DH shared key
      u.genKey(dh_key_server_public)
      u.genHashSecret1(W, dh_key_server_public)
      server_socket.sendto(str(nonce2)+u.hashsecret1, (serverIP, int(Dport)))
   else:
      print('Hashes do not match' )
      sys.exit(2)

   (dataRecv, addr) = server_socket.recvfrom(4096)
   offset =InitOffset
   iv = dataRecv[offset:offset+LengthIV]
   offset += LengthIV
   ciphertext = dataRecv[offset:len(dataRecv)]
   dh_aes_key = aeskeygen(u.key)
 
   # Decrypt the ciphertext using the key_sym and iv
   plaintext = AESDecrypt(dh_aes_key, iv, ciphertext)
   msg = str(bytes(plaintext))
   print('Received ACK')

   networkinfo = client_socket.getsockname()[0] + ',' + str(client_socket.getsockname()[1])

   # Encrypt the network info using DH Key
   iv = os.urandom(LengthIV)
   nwinfo = AESEncrypt(networkinfo, dh_aes_key, iv)

   # Encrypt username and encrypted networkinfo using new aes key , and encrypt sym key using rsa server ublic key
   new_iv = os.urandom(LengthIV)
   new_sym_key = keygen()
   msg_nwinfo = username + ',' + bytes(nwinfo)
   encrypted_msg = AESEncrypt(msg_nwinfo, new_sym_key, new_iv)

   # Encrypt the symmetric key with rsa public key
   cipher_new_key = RSAEncrypt(new_sym_key, serverpubkey)

   info_msg = bytes(new_iv) + bytes(iv) + bytes(cipher_new_key) + bytes(encrypted_msg)
   print('Sending common port info and peer AuthKey')
   server_socket.sendto(info_msg, (serverIP, int(Dport)))  
   pass
Example #10
0
def MsgSendSequence(peername, msg):
   # Fetch user info from server
   global dh_aes_key
   global serverpubkey
   global serverIP
   global username

   dynamic_socket = None
   try:
      # Format of send command {Alice,K{send Bob}} server-public-key
      # Encrypt the list command using the DH shared key
      N1 = os.urandom(LengthN) 
      iv = os.urandom(LengthIV)
      sendinfo = AESEncrypt('send '+peername, dh_aes_key, iv)
      send_msg = bytes(N1) + bytes(username + ',' + str(sendinfo))

      # Encrypt username and list command using new aes key and then encrypt the aes key using server public key
      sym_key = keygen()
      encrypted_send = AESEncrypt(send_msg, sym_key, iv)

      cipher_sym_key = RSAEncrypt(sym_key, serverpubkey)
      send_msg = bytes(0x01) + bytes(iv) + bytes(cipher_sym_key) + bytes(encrypted_send)
      print('Sending send command')
      server_socket.sendto(send_msg, (serverIP, int(serverPort)))
      (Dport, addr) = server_socket.recvfrom(4096)

      # Receive peer info from the server 
      (dataRecv, addr) = server_socket.recvfrom(4096)
      offset = InitOffset
      iv1 = dataRecv[offset:offset+LengthIV]
      offset += LengthIV
      ciphernew = dataRecv[offset:len(dataRecv)]

      # Decrypt ciphernew
      peerInfo = AESDecrypt(dh_aes_key, iv1, ciphernew)
      (peerCommKey, comm_private_key, dynamic_socket, D_addr) = AuthSequenceA(peerInfo)

      # Encrypt msg and send it to peer
      if (peerCommKey == None or comm_private_key == None):
         print "Sending msg failed"
      else:
         peerCommKey = serialization.load_pem_public_key(
             peerCommKey,
             backend=default_backend()
         )
         comm_private_key = serialization.load_pem_private_key(
            comm_private_key,
            password=None,
            backend=default_backend()
         )
         msg = encryptSendMsg(peerCommKey, comm_private_key, msg)
         dynamic_socket.sendto(msg, (D_addr[0],int(D_addr[1])))
      print "Message has been sent"
   except socket.timeout:
      print "Timeout... please try to re-send the command"
   except:
      print "Unexpected error:", sys.exc_info()[0]
   finally:
      if dynamic_socket != None:
         dynamic_socket.close()
      return
Example #11
0
def AuthSequenceB(dynamic_socket, peerAdd, init_msg):
   global server_socket
   global sender_private_key
   global dh_aes_key

   print "AuthSequenceB"

   # Decrypt peer's user name
   dataRecv = RSADecrypt(init_msg, sender_private_key)
   r2 = dataRecv[0:LengthN]
   peername = str(dataRecv[LengthN:len(dataRecv)])

   # Fetch peer's AuthKey
   N1 = os.urandom(LengthN) 
   iv = os.urandom(LengthIV)  
   sendinfo = AESEncrypt('send '+ peername, dh_aes_key, iv)
   send_msg = bytes(N1) + bytes(username + ',' + sendinfo)

   # Encrypt send_msg using new aes key and then encrypt the aes key using server public key
   sym_key = keygen()
   encrypted_send = AESEncrypt(send_msg, sym_key, iv)

   cipher_sym_key = RSAEncrypt(sym_key, serverpubkey)
   send_msg = bytes(0x01) + bytes(iv) + bytes(cipher_sym_key) + bytes(encrypted_send)
   print('Sending send command')
   server_socket.sendto(send_msg, (serverIP, int(serverPort)))

   (Dport, addr) = server_socket.recvfrom(4096)
   # Receive peer info from the server 
   (dataRecv, addr) = server_socket.recvfrom(4096)
   offset = InitOffset
   iv1 = dataRecv[offset:offset+LengthIV]
   offset += LengthIV
   ciphernew = dataRecv[offset:len(dataRecv)]

   # Decrypt ciphernew
   peerInfo = AESDecrypt(dh_aes_key, iv1, ciphernew)
   peerAdd_s = peerInfo.split(',')[0]
   if peerAdd_s!=peerAdd[0]:
      print "Peer doesn't match... maybe impersonated..."
      return

   peerRSAKey = peerInfo.split(',')[2]
   peerRSAKey =  serialization.load_pem_public_key(peerRSAKey, backend=default_backend())

   # Finish the authentication
   r1 = os.urandom(LengthN)
   r1_e = RSAEncrypt(r1, peerRSAKey)
   msg = bytes(r2)+bytes(r1_e)
   print "Send reply to peer: " + peerAdd[0] + " : " + str(peerAdd[1])
   dynamic_socket.sendto(msg, (peerAdd[0], int(peerAdd[1])))

   # Waiting for CommKey
   (dataRecv, addr) = dynamic_socket.recvfrom(4096)
   r1_d = dataRecv[InitOffset:LengthN]
   if r1_d!=r1:
      print 'Verification failed'
      return
   peerRSACommKey = dataRecv[LengthN:len(dataRecv)]
   peerRSACommKey = decryptSendMsg(peerRSACommKey, sender_private_key, peerRSAKey)

   # Generate CommKey and send to peer
   try:
      comm_private_key = rsa.generate_private_key(
      public_exponent=65537,
      key_size=2048,
      backend=default_backend())
   except:
      print("The provided backend does not implement RSABackend")
      return None

   # Obtain the public key from the private key generated using RSA
   comm_public_key = comm_private_key.public_key()
   try:
      pem = comm_public_key.public_bytes(
           encoding=serialization.Encoding.PEM,
           format=serialization.PublicFormat.SubjectPublicKeyInfo)
      pem_s = comm_private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()
   )
   except:
      print("Serialization failed")
      return None
   key = serialization.load_pem_public_key(peerRSACommKey, backend=default_backend())
   pem_cipher = encryptSendMsg(key, sender_private_key, pem)
   dynamic_socket.sendto(pem_cipher, (peerAdd[0], int(peerAdd[1])))

   return (peername, pem_s, peerRSACommKey)
Example #12
0
def LoginSequence(dynamic_socket, addr, dataRecv):
   global user_DHkey
   global user_networkinfo
   global serverprivkey

   print 'LoginSequence'
 
   # msg format greeting_msg = bytes(0x00)  + bytes(iv) + bytes(cipher_key_sym) + bytes(ciphertext)
   cipher_key_sym = None
   ciphertext = None
   iv = None
   moduli = None

   offset = InitOffset	                               # Initial offset
   msg_type = dataRecv[offset] 		               # byte 0 contains the msg_type
   offset += LengthType
   iv = dataRecv[offset:offset+16]		       # 16 bytes of IV
   offset += LengthIV
   cipher_key_sym = dataRecv[offset:offset+256]	       # 256 bytes of the symmetric key
   offset += LengthKey
   ciphertext = dataRecv[offset:len(dataRecv)]	       # The encrypted text

   # Load Private key of the server
   try:
       with open('serverprivkey.pem', 'rb') as f:
            serverprivkey = serialization.load_pem_private_key(f.read(), password=None, backend=default_backend())
   except:
       print("The file specified does not exist")
       sys.exit(2)

   # Decrypt key_sym with reciever's private key
   key_sym = RSADecrypt(cipher_key_sym, serverprivkey)

   # Decrypt the ciphertext using the key_sym and iv
   plaintext = AESDecrypt(key_sym, iv , ciphertext)
   N1 = bytes(plaintext)[0:32]
   plaintext = str(bytes(plaintext[32:len(bytes(plaintext))]))
   
   # Get data from plaintext
   split_data = plaintext.split(',')
   username = split_data[0]

   # Check if the user already exists
   try:
    if user_networkinfo[username] != [] or user_DHkey[username] != None:
      print "User has already logged in!"
      return
   except:
    print "User doesn't exist!"
    return

   # DH public key - 2^a mod p and rsa public key of the client
   client_dh_pub_key = split_data[1]
   client_rsa_pub_key = split_data[2]
   client_rsa_auth_key =  serialization.load_pem_public_key(client_rsa_pub_key, backend=default_backend())

   u = DiffieHellman()
   b = str(u.privateKey)                             # DH private key of the server
   dh_key_server = str(u.publicKey)                  # DH public key of the server - 2^b mod p
   p = str(u.prime)                                  # p - prime number for DH
   moduli = user_moduli[username]                    # 2^W mod p
   u.genHashSecretM(moduli ,client_dh_pub_key)
   N2 = os.urandom(LengthN)
   msg = N1 + N2 + u.hashsecret + dh_key_server

   # Generate a aes key , iv and use it to encrypt the above msg
   aes_key = keygen()
   iv = os.urandom(LengthIV)
   ciphertext = AESEncrypt(msg, aes_key, iv)

   # Encrypt the symmetric key with client's rsa public key
   cipher_key_sym = RSAEncrypt(aes_key, client_rsa_auth_key)

   # Constant for GREETING is 0x00
   server_first_msg = bytes(0x00)  + bytes(iv) + bytes(cipher_key_sym) + bytes(ciphertext)
   print 'Received Greeting from: ',username

   dynamic_socket.sendto(server_first_msg, (addr[0], int(addr[1])))

   (dataRecv, addr) = dynamic_socket.recvfrom(4096)
   print 'Verifying the hashes for ', username
   _N2 = dataRecv[0:LengthN]
   if _N2!=str(N2):
    print "Nonce N2 doesn't match"
    return
  
   u.genHashSecretM1(moduli ,client_dh_pub_key)
   hash_recv = dataRecv[LengthN:len(dataRecv)]
   if hash_recv == u.hashsecret1:
      u.genKey(client_dh_pub_key)
   else:
      print 'Hashes does not match'
      return
   print 'Sending ACK to ' , username

   sym_key_shared = aeskeygen(u.key)                              # Generate AES key out of DH key
   iv = os.urandom(LengthIV)
   acknowledge = AESEncrypt('ACK', sym_key_shared, iv)            # Encrypt the ACK with the symmetric key
   msg = bytes(iv) + bytes(acknowledge)
   dynamic_socket.sendto(msg, (addr[0], int(addr[1])))            # Send the ACK to the client

   print 'Waiting for Network Information of ',username
   (dataRecv, addr) = dynamic_socket.recvfrom(4096)
   offset = InitOffset
   new_iv = dataRecv[offset:offset+LengthIV]
   offset += LengthIV
   iv = dataRecv[offset:offset+LengthIV]
   offset += LengthIV
   cipher_key_new = dataRecv[offset:offset+LengthKey]
   offset += LengthKey
   nwciphertext = dataRecv[offset:len(dataRecv)]

   # Decrypt cipher_key_new with server's private key
   new_key_sym = RSADecrypt(cipher_key_new, serverprivkey)

   # Decrypt the nwciphertext using symmetric key decryption
   plaintext = AESDecrypt(new_key_sym, new_iv, nwciphertext)
   user = plaintext.split(',')[0]
   enc_nwinfo = plaintext[len(user)+1:len(plaintext)]

   # Decrypt the nwinfo using DH key
   plaintext = AESDecrypt(sym_key_shared, iv, enc_nwinfo)
   ip_address = plaintext.split(',')[0]
   port_num = plaintext.split(',')[1]
   #print('Received common port and ip')
  
   # Register the client's network info along with the client rsa public key into user_networkinfo table
   user_networkinfo[username].append(ip_address)
   user_networkinfo[username].append(port_num)
   user_networkinfo[username].append(client_rsa_pub_key)
   
   # Register the DH shared key in the user_DHkey table
   user_DHkey[username] = sym_key_shared

   print('LOGIN SUCCESSFUL')
   print('------------------------------------------------------------------')
   pass