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