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
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
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('')
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('')
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
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
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
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)
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
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
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)
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