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 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 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