def test_rsa(self): key_one = Gen.generate_key_pair("unittest1") key_two = Gen.generate_key_pair("unittest2") f = open('private_unittest1.pem', 'rb') private_key_one = f.read() f.close() f = open('public_unittest1.pem', 'rb') public_key_one = f.read() f.close() f = open('private_unittest2.pem', 'rb') private_key_two = f.read() f.close() input_msg = "Hello There" # Correct Decryption encrypted_msg = Crypto_Functions.rsa_encrypt(input_msg, public_key_one) output_msg = Crypto_Functions.rsa_decrypt(encrypted_msg, private_key_one) self.assertEqual(input_msg, output_msg) # Incorrect Decryption with self.assertRaises(ValueError): Crypto_Functions.rsa_decrypt(encrypted_msg, private_key_two) os.remove("private_unittest1.pem") os.remove("public_unittest1.pem") os.remove("private_unittest2.pem") os.remove("public_unittest2.pem")
def send_group_handshake(sender, recipient, members, s, sender_private_key, recipient_public_key, key, group_name): """ Send a handshake to each group member. Does not update anything directly """ # RSA encrypt the msg key_b64 = base64.b64encode(key) encrypt_msg = sender + "," + "_".join(members) + "," + str(key_b64) encrypted = Crypto_Functions.rsa_encrypt(encrypt_msg, recipient_public_key) encrypted_b64 = base64.b64encode(encrypted) # Create a signature for the message contents signature = (sender + ",".join(members) + str(encrypted_b64)).encode() signed = Crypto_Functions.rsa_sign(signature, sender_private_key) signed_b64 = base64.b64encode(signed) # Transform key into two keys aes_key, hmac_key = Crypto_Functions.hash_keys(key) request = Requests.initiate_group_chat(sender, recipient, ",".join(members), str(encrypted_b64), str(signed_b64), group_name) s.send(request) return {"aes": aes_key, "hmac": hmac_key}
def receive_direct_handshake(data, contacts, sender_public_key, recipient_private_key): ''' Receiving direct private message handshake. Does not update directly ''' sender = data["requester"] recipient = data["recipient"] encrypted_b64 = data["encrypted"] signed_b64 = data["signed"] encrypted = base64.b64decode(encrypted_b64.encode()[2:-1]) signed = base64.b64decode(signed_b64.encode()[2:-1]) signature_contents = (sender + recipient + str(encrypted_b64)).encode() if not Crypto_Functions.rsa_check_sign(signature_contents, signed, sender_public_key): print("Invalid signature") return {} else: # Parse encrpyted message decrypted_msg = Crypto_Functions.rsa_decrypt(encrypted, recipient_private_key) decrypted_msg_split = decrypted_msg.split(",", 2) # Check the contents of the sender and re enc_sender = decrypted_msg_split[0] enc_recipient = decrypted_msg_split[1] key_b64 = decrypted_msg_split[2].encode()[2:-1] key = base64.b64decode(key_b64) # Transform key into two keys aes_key, hmac_key = Crypto_Functions.hash_keys(key) return {"aes": aes_key, "hmac": hmac_key}
def send_direct_handshake(sender, recipient, s, sender_private_key, recipient_public_key): """" Send the direct handshake to a user. Does not update anything directly. """ # Message contents key = Crypto_Functions.generate_session_key() # RSA encrypt the msg key_b64 = base64.b64encode(key) encrypt_msg = sender + "," + recipient + "," + str(key_b64) encrypted = Crypto_Functions.rsa_encrypt(encrypt_msg, recipient_public_key) encrypted_b64 = base64.b64encode(encrypted) # Create a signature for the message contents signature = (sender + recipient + str(encrypted_b64)).encode() signed = Crypto_Functions.rsa_sign(signature, sender_private_key) signed_b64 = base64.b64encode(signed) # Transform key into two keys aes_key, hmac_key = Crypto_Functions.hash_keys(key) request = Requests.initiate_direct_message(sender, recipient, str(encrypted_b64), str(signed_b64)) s.send(request) return {"aes": aes_key, "hmac": hmac_key}
def test_hash_keys(self): key = Crypto_Functions.generate_session_key() key1, key2 = Crypto_Functions.hash_keys(key) self.assertNotEqual(key1, key2, key) self.assertEqual([len(key), len(key1), len(key2)], [32, 32, 32])
def send_group_handshake(self, group_name, group_members): """ Same as send_handshake() but handles sending to mulitple members and providing the correct information """ # Initialize the group dict self.groups[group_name] = {} self.groups[group_name]["members"] = group_members # Send a handshake to each member in the group key = Crypto_Functions.generate_session_key() for recipient in group_members: # Make sure we have a public key if recipient not in self.contacts.keys( ) or "public_key" not in self.contacts[recipient]: self.populate_public_keys(recipient) keys = Send.send_group_handshake( self.username, recipient, group_members, self.s, self.private_key, self.contacts[recipient]["public_key"], key, group_name) self.groups[group_name]["aes_key"] = keys["aes"] self.groups[group_name]["hmac_key"] = keys["hmac"] email = self.username group_aes = base64.b64encode(self.groups[group_name]["aes_key"]) enc_group_aes, iv_aes = Crypto_Functions.aes_encrypt( str(group_aes), self.password_aes) enc_group_aes = str(base64.b64encode(enc_group_aes)) iv_aes = str(base64.b64encode(iv_aes)) # Get encrypted hmac under self.password_aes hmac_key = base64.b64encode(self.groups[group_name]["hmac_key"]) enc_hmac_key, iv_hmac = Crypto_Functions.aes_encrypt( str(hmac_key), self.password_aes) enc_hmac_key = str(base64.b64encode(enc_hmac_key)) iv_hmac = str(base64.b64encode(iv_hmac)) for member in group_members: contact = member # Create the signature signature_contents = email + contact + enc_group_aes + enc_hmac_key + iv_aes + iv_hmac # signature_contents) signature = str( Crypto_Functions.hmac_b64(signature_contents.encode(), self.password_hmac)) Database.add_group(self.username, group_name, member, signature, enc_group_aes, iv_aes, enc_hmac_key, iv_hmac)
def populate_public_keys(self, username: str): """ Access the database and get a contacts public key """ # Get the public key from the data base info = Database.get_user_info(username) # Check if it exists and fields are correct keys = ("user", "public_key", "ca_signature") if info == {}: print("The user you requested was not found in the database. ") return for key in keys: if not key in info or not info[key]: print("A public key value is missing") return public_key_b64 = info["public_key"].encode()[2:-1] ca_signature_b64 = info["ca_signature"].encode()[2:-1] public_key = base64.b64decode(public_key_b64) ca_signature = base64.b64decode(ca_signature_b64) # Check the CA's signature signature_contents = username + "," + public_key.decode() if not Crypto_Functions.rsa_check_sign( signature_contents.encode(), ca_signature, self.ca_public_key): print("The requested public key and signature do not match for " + username) return if username not in self.contacts: self.contacts[username] = dict() self.contacts[username]["public_key"] = public_key
def receive_direct(data, contacts, received_timestamps): """ Receiving direct private messages. Does necessary message conversion and checking then prints output """ sender = data["sender"] # Decode messages enc_msg_b64 = data["message"].encode()[2:-1] iv_b64 = data["iv"].encode()[2:-1] enc_msg = base64.b64decode(enc_msg_b64) iv = base64.b64decode(iv_b64) # Get shared key aes_key = contacts[sender]["aes_key"] hmac_key = contacts[sender]["hmac_key"] # Get timestamp msg_timestamp = data["timestamp"] current_timestamp = datetime.datetime.now().timestamp() # Check if the timestamp is accurate. If exceeds 20 seconds, then is deemed a replay if current_timestamp - float(msg_timestamp) > 20: print("Large difference in time sent and time recieved. Message was not received.") return # Check if the timestamp was already seen if msg_timestamp in received_timestamps and received_timestamps[msg_timestamp] == sender: print("There was an attempt at a replay attack, the message will not be viewed") return received_timestamps[msg_timestamp] = sender # Check tag tag = data["tag"] tag = base64.b64decode(tag.encode()[2:-1]) tag_contents = str(base64.b64encode(enc_msg)) + msg_timestamp valid = Crypto_Functions.check_hmac_b64(tag_contents.encode(), tag, hmac_key) if not valid: raise Exception("HMAC not valid") # Decrypt message decrypted_msg = Crypto_Functions.aes_decrypt(enc_msg, iv, aes_key) print(sender + ": " + decrypted_msg) return msg_timestamp
def receive_group_handshake(data, sender, groups, contacts, private_key): """ Receiving handshake from group message. Does not update directly """ if sender in data["recipients"].split(","): # Parsed message contents requester = data["requester"] encrypted_b64 = data["encrypted"] signed_b64 = data["signed"] encrypted = base64.b64decode(encrypted_b64.encode()[2:-1]) signed = base64.b64decode(signed_b64.encode()[2:-1]) # Check the signature members = data["recipients"].split(",") signature_contents = (requester + ",".join(members) + str(encrypted_b64)).encode() if not Crypto_Functions.rsa_check_sign(signature_contents, signed, contacts[requester]["public_key"]): print("Invalid signature") else: # Parse encrpyted message decrypted_msg = Crypto_Functions.rsa_decrypt(encrypted, private_key) decrypted_msg_split = decrypted_msg.split(",", 2) # Check the contents of the sender and re enc_sender = decrypted_msg_split[0] enc_recipient = decrypted_msg_split[1] key_b64 = decrypted_msg_split[2].encode()[2:-1] key = base64.b64decode(key_b64) # Transform key into two keys aes_key, hmac_key = Crypto_Functions.hash_keys(key) group_name = data["group_name"] return {"aes": aes_key, "hmac": hmac_key, "members": members, "group_name": group_name} else: print("User doesn't match intended recipient") return {}
def send_direct_handshake(self, recipient): """ Sends a handshake to the recipient to establish secure channels. Also updates the contact information """ # Send handshake keys = Send.send_direct_handshake( self.username, recipient, self.s, self.private_key, self.contacts[recipient]["public_key"]) # Update recipient's keys self.contacts[recipient]["aes_key"] = keys["aes"] self.contacts[recipient]["hmac_key"] = keys["hmac"] email = self.username contact = recipient # Get encrypted aes under self.password_aes contact_aes = base64.b64encode(keys["aes"]) enc_contact_aes, iv_aes = Crypto_Functions.aes_encrypt( str(contact_aes), self.password_aes) enc_contact_aes = str(base64.b64encode(enc_contact_aes)) iv_aes = str(base64.b64encode(iv_aes)) # Get encrypted hmac under self.password_aes hmac_key = base64.b64encode(keys["hmac"]) enc_hmac_key, iv_hmac = Crypto_Functions.aes_encrypt( str(hmac_key), self.password_aes) enc_hmac_key = str(base64.b64encode(enc_hmac_key)) iv_hmac = str(base64.b64encode(iv_hmac)) # Create the signature signature_contents = self.username + contact + enc_contact_aes + enc_hmac_key + iv_aes + iv_hmac signature = str( Crypto_Functions.hmac_b64(signature_contents.encode(), self.password_hmac)) # Update the database Database.add_contact_info(email, contact, enc_contact_aes, signature, iv_aes, enc_hmac_key, iv_hmac)
def send_direct(sender, recipient, contacts, message, s): """ Sends an encrypted direct message to the recipient. """ # Get keys aes_key = contacts[recipient]["aes_key"] hmac_key = contacts[recipient]["hmac_key"] # Encrypt enc_msg, iv = Crypto_Functions.aes_encrypt(message, aes_key) # Create message tag on encypted data timestamp = str(datetime.datetime.now().timestamp()) tag_contents = str(base64.b64encode(enc_msg)) + timestamp tag = Crypto_Functions.hmac_b64(tag_contents.encode(), hmac_key) # Encoding enc_msg_b64 = base64.b64encode(enc_msg) iv_b64 = base64.b64encode(iv) s.send(Requests.direct_message(sender, recipient, str(enc_msg_b64), str(iv_b64), timestamp, str(tag)))
def test_rsa_sign(self): key_one = Gen.generate_key_pair("unittest1") key_two = Gen.generate_key_pair("unittest2") f = open('private_unittest1.pem', 'rb') private_key_one = f.read() f.close() f = open('public_unittest1.pem', 'rb') public_key_one = f.read() f.close() f = open('private_unittest2.pem', 'rb') private_key_two = f.read() f.close() input_msg = b"Hello There" # Correct checking of signature sign = Crypto_Functions.rsa_sign(input_msg, private_key_one) self.assertTrue( Crypto_Functions.rsa_check_sign(b"Hello There", sign, public_key_one)) # Incorrect msg sign = Crypto_Functions.rsa_sign(input_msg, private_key_one) self.assertFalse( Crypto_Functions.rsa_check_sign(b"Hello", sign, public_key_one)) # Incorrect checking of signature sign = Crypto_Functions.rsa_sign(input_msg, private_key_two) self.assertFalse( Crypto_Functions.rsa_check_sign(b"Hello There", sign, public_key_one))
def test_hmac(self): key_one = Crypto_Functions.generate_session_key() key_two = Crypto_Functions.generate_session_key() msg = b"Hello There" # Correct tag = Crypto_Functions.hmac(msg, key_one) self.assertTrue(Crypto_Functions.check_hmac(msg, tag, key_one)) # Incorrect tag = Crypto_Functions.hmac(msg, key_two) self.assertFalse(Crypto_Functions.check_hmac(msg, tag, key_one)) tag = Crypto_Functions.hmac(msg, key_one) self.assertFalse(Crypto_Functions.check_hmac(b"Hello", tag, key_one))
def send_group_message(message, sender, group_name, s, group_members, groups): """ Send a message to each member in the group. This is done through one send request """ # Get shared key aes_key = groups[group_name]["aes_key"] hmac_key = groups[group_name]["hmac_key"] # Encrypt enc_msg, iv = Crypto_Functions.aes_encrypt(message, aes_key) # Create message tag on encypted data timestamp = str(datetime.datetime.now().timestamp()) tag_contents = str(base64.b64encode(enc_msg)) + timestamp tag = Crypto_Functions.hmac_b64(tag_contents.encode(), hmac_key) # Encoding enc_msg_b64 = base64.b64encode(enc_msg) iv_b64 = base64.b64encode(iv) s.send(Requests.group_message(sender, ",".join(group_members), group_name, str(enc_msg_b64), str(iv_b64), timestamp, str(tag)))
def populate_private_key(self): """ Populate the public key from the database. This is used when a user logs in """ info = Database.get_user_account(self.username) if "private_key" not in info: self.private_key = b"" return False private_key_enc = base64.b64decode(info["private_key"].encode()[2:-1]) iv = base64.b64decode(info["aes_iv"].encode()[2:-1]) tag = base64.b64decode(info["tag"].encode()[2:-1]) tag_contents = info["private_key"] + info["aes_iv"] if not Crypto_Functions.check_hmac_b64(tag_contents.encode(), tag, self.password_hmac): self.private_key = b"" return False private_key_b64 = Crypto_Functions.aes_decrypt(private_key_enc, iv, self.password_aes) private_key = base64.b64decode(private_key_b64.encode()[2:-1]) self.private_key = private_key return True
def test_aes(self): key_one = Crypto_Functions.generate_session_key() key_two = Crypto_Functions.generate_session_key() input_msg = "Hello" # Correct Decryption encrypted, iv = Crypto_Functions.aes_encrypt(input_msg, key_one) output_msg = Crypto_Functions.aes_decrypt(encrypted, iv, key_one) self.assertEqual(input_msg, output_msg) # Incorrect Decryption with self.assertRaises(ValueError): Crypto_Functions.aes_decrypt(encrypted, iv, key_two)
def handle_receive(self, data, c): request = Requests.parse_request(data) if len(request.data) == 0: print( "There was in issue with the received data. Received the following raw data: ", data) elif request.is_ca_request(): username = request.data["username"] print("New request. Username: "******"Username " + username + " exists in the CA database.") ca_response = Requests.ca_response_invalid() c.send(ca_response) else: public_key_b64 = request.data["public_key"].encode()[2:-1] public_key = base64.b64decode(public_key_b64) message = username + "," + public_key.decode() ca_signature = Crypto_Functions.rsa_sign( message.encode(), self.private_key) ca_signature_b64 = base64.b64encode(ca_signature) ca_response = Requests.ca_response_valid( username, request.data["public_key"], str(ca_signature_b64)) print("Signed public key for the user: "******"Adding user info to the CA database.") CA_Database.add_user(username, request.data["public_key"], str(ca_signature_b64)) print("Sending the signature back to the client.") c.send(ca_response) elif request.is_send_email(): username = request.data["username"] print("CA received email: " + username) self.send_email(username) elif request.is_verify_email(): code = request.data["code"] if (self.verify_code(code)): ca_response = Requests.ca_response_email_valid() c.send(ca_response) else: ca_response = Requests.ca_response_email_invalid() c.send(ca_response)
def login(self): """ Login to the user account. This involves setting all contact information by pulling and decrypting information from the database """ self.username = input("Please enter email: ") password = input("Please enter your password: "******"Account not verified. Please check username and password and try again." ) self.authenticate() return # Receive contact information that is stored in the database contacts = Database.get_user_contact_info(self.username) for contact in contacts: # Ensure necesary information is there keys = ("contact", "contact_aes", "hmac_key", "signature", "iv_aes", "iv_hmac") invalid = False for key in keys: # Make sure all the keys are present if key not in contact: invalid = True print("Not all fields in contact return") if invalid: continue for key in keys: if not contact[key]: # Make sure each entry has a value print("Not all fields in contact have value return") invalid = True if invalid: continue # Get contact info recipient = contact["contact"] enc_aes_b64 = contact["contact_aes"].encode()[2:-1] enc_aes = base64.b64decode(enc_aes_b64) enc_hmac_b64 = contact["hmac_key"].encode()[2:-1] enc_hmac = base64.b64decode(enc_hmac_b64) signed_b64 = contact["signature"].encode()[2:-1] signed = base64.b64decode(signed_b64) iv_aes_b64 = contact["iv_aes"].encode()[2:-1] iv_aes = base64.b64decode(iv_aes_b64) iv_hmac_b64 = contact["iv_hmac"].encode()[2:-1] iv_hmac = base64.b64decode(iv_hmac_b64) # Check signature signature_contents = self.username + recipient + contact[ "contact_aes"] + contact["hmac_key"] + contact[ "iv_aes"] + contact["iv_hmac"] if not Crypto_Functions.check_hmac_b64(signature_contents.encode(), signed, self.password_hmac): print( "The password you entered does not match the stored data. This could be caused by an incorrect password, or the data could be corrupted." ) self.login() return # Decrypt keys try: aes_key = Crypto_Functions.aes_decrypt(enc_aes, iv_aes, self.password_aes) aes_key = base64.b64decode(aes_key.encode()[2:-1]) hmac_key = Crypto_Functions.aes_decrypt( enc_hmac, iv_hmac, self.password_aes) hmac_key = base64.b64decode(hmac_key.encode()[2:-1]) self.contacts[recipient] = { "aes_key": aes_key, "hmac_key": hmac_key } except: print("Incorrect Decryption") # Reveive group information that is stored in the database groups = Database.get_username_groups(self.username) for contact in groups: # Ensure necesary information is there # print("12", contact) keys = ("group_name", "participant", "aes_key", "hmac_key", "signature", "aes_iv", "hmac_iv") invalid = False for key in keys: # Make sure all the keys are present if key not in contact: print("Not all fields in contact return 1") invalid = True if invalid: continue for key in keys: if not contact[key]: # Make sure each entry has a value print("Not all fields in contact have value return 1") invalid = True if invalid: continue # Get information from database line group_name = contact["group_name"] recipient = contact["participant"] enc_aes_b64 = contact["aes_key"].encode()[2:-1] enc_aes = base64.b64decode(enc_aes_b64) enc_hmac_b64 = contact["hmac_key"].encode()[2:-1] enc_hmac = base64.b64decode(enc_hmac_b64) signed_b64 = contact["signature"].encode()[2:-1] signed = base64.b64decode(signed_b64) iv_aes_b64 = contact["aes_iv"].encode()[2:-1] iv_aes = base64.b64decode(iv_aes_b64) iv_hmac_b64 = contact["hmac_iv"].encode()[2:-1] iv_hmac = base64.b64decode(iv_hmac_b64) # Check the signature # signature_contents = email + contact + enc_group_aes + enc_hmac_key + iv_aes + iv_hmac # signature = str(Crypto_Functions.hmac_b64(signature_contents.encode(), self.password_hmac)) signature_contents = self.username + recipient + contact[ "aes_key"] + contact["hmac_key"] + contact["aes_iv"] + contact[ "hmac_iv"] # print(signature_contents) if not Crypto_Functions.check_hmac_b64(signature_contents.encode(), signed, self.password_hmac): print( "The password you entered does not match the stored data. This could be caused by an incorrect password, or the data could be corrupted." ) self.login() return # Decrypt keys try: aes_key = Crypto_Functions.aes_decrypt(enc_aes, iv_aes, self.password_aes) aes_key = base64.b64decode(aes_key.encode()[2:-1]) hmac_key = Crypto_Functions.aes_decrypt( enc_hmac, iv_hmac, self.password_aes) hmac_key = base64.b64decode(hmac_key.encode()[2:-1]) # Make sure group has been added to group dict if group_name not in self.groups: self.groups[group_name] = {} # Group has already been added to groups dict self.groups[group_name]["aes_key"] = aes_key self.groups[group_name]["hmac_key"] = hmac_key # Member list already created and current recipient not in it if "members" in self.groups[ group_name] and recipient not in self.groups[ group_name]: self.groups[group_name]["members"].append(recipient) # If the user isn't in list add them to a new list elif recipient not in self.groups[group_name]: self.groups[group_name]["members"] = [recipient] except: print("Incorrect Decryption") request = Requests.login(self.username) self.s.send(request) self.loggedin = True print("Welcome, " + self.username + "!") print( "You're currently in the listening mode. To issue a command, press ENTER. You can type :help to see all the available commands." )
def handle_receive(self): """ Handles all of the different receiving requests from server """ while True: data = self.s.recv(4096) request = Requests.parse_request(data) with self.console_lock: # Handle different message types if request.is_direct_message(): Receive.receive_direct(request.data, self.contacts, self.received_timestamps) elif request.is_group_message(): Receive.receive_group(request.data, self.groups, self.received_timestamps) elif request.is_broadcast(): print(request.data["message"]) # Initiate the group chat and save keys elif request.is_initiate_group_chat(): print("Initiating new group chat...") requester = request.data["requester"] # Make sure we have the contact if requester not in self.contacts or "public_key" not in self.contacts[ requester].keys(): self.populate_public_keys(requester) # Recieve the handshake keys = Receive.receive_group_handshake( request.data, self.username, self.groups, self.contacts, self.private_key) group_name = keys["group_name"] aes_key = keys["aes"] hmac_key = keys["hmac"] members = keys["members"] # This will completely overwrite or add a new one self.groups[group_name] = { "aes_key": aes_key, "hmac_key": hmac_key, "members": members } email = self.username # Get encrypted aes under self.password_aes group_aes = str(base64.b64encode(aes_key)) enc_goup_aes, iv_aes = Crypto_Functions.aes_encrypt( group_aes, self.password_aes) enc_goup_aes = str(base64.b64encode(enc_goup_aes)) iv_aes = str(base64.b64encode(iv_aes)) # get encrypted hmac under self.password_aes hmac_key = str(base64.b64encode(hmac_key)) enc_hmac_key, iv_hmac = Crypto_Functions.aes_encrypt( hmac_key, self.password_aes) enc_hmac_key = str(base64.b64encode(enc_hmac_key)) iv_hmac = str(base64.b64encode(iv_hmac)) # Add line for each member for member in members: contact = member signature_contents = email + contact + enc_goup_aes + enc_hmac_key + iv_aes + iv_hmac signature = str( Crypto_Functions.hmac_b64( signature_contents.encode(), self.password_hmac)) Database.add_group(self.username, group_name, contact, signature, enc_goup_aes, iv_aes, enc_hmac_key, iv_hmac) elif request.is_initiate_direct_message(): requester = request.data["requester"] if requester not in self.contacts: self.populate_public_keys(requester) keys = Receive.receive_direct_handshake( request.data, self.contacts, self.contacts[requester]["public_key"], self.private_key) aes_key = keys["aes"] hmac_key = keys["hmac"] # This will add or overwrite two fields to the requester's contact, leaving the others self.contacts[requester]["aes_key"] = aes_key self.contacts[requester]["hmac_key"] = hmac_key email = self.username contact = requester # Get encrypted aes under self.password_aes contact_aes = str(base64.b64encode(aes_key)) enc_contact_aes, iv_aes = Crypto_Functions.aes_encrypt( contact_aes, self.password_aes) enc_contact_aes = str(base64.b64encode(enc_contact_aes)) iv_aes = str(base64.b64encode(iv_aes)) # Get encrypted hmac under self.password_aes hmac_key = str(base64.b64encode(hmac_key)) enc_hmac_key, iv_hmac = Crypto_Functions.aes_encrypt( hmac_key, self.password_aes) enc_hmac_key = str(base64.b64encode(enc_hmac_key)) iv_hmac = str(base64.b64encode(iv_hmac)) # Create the signature signature_contents = self.username + contact + enc_contact_aes + enc_hmac_key + iv_aes + iv_hmac signature = str( Crypto_Functions.hmac_b64(signature_contents.encode(), self.password_hmac)) Database.add_contact_info(email, contact, enc_contact_aes, signature, iv_aes, enc_hmac_key, iv_hmac)
def create_account(self): valid_username = False while not valid_username: self.username = input("Enter email: ") if (Database.check_user(self.username)): print("Username already exists in the system.") else: valid_username = True # Here for email verification valid_email = False while not valid_email: email = self.username print(email) if not self.check_email_valid(email): print("Email entered not valid") self.create_account() else: request = Requests.send_email(email) self.ca.send(request) code = input( "Please enter the verification code sent to your email address: " ) request2 = Requests.verify_email(code) self.ca.send(request2) data = self.ca.recv(4096) request = Requests.parse_request(data) if request.is_ca_response_email_valid(): print("Authentication was successful") valid_email = True elif request.is_ca_response_email_invalid(): print("Code was not valid. Please try again.") strong_password = False while not strong_password: password = input("Create new password: "******"Waiting for CA...") data = self.ca.recv(4096) request = Requests.parse_request(data) if len(request.data) == 0: print( "There was in issue with the received data. Received the following raw data: ", data) elif request.is_ca_response_valid(): print("Received a valid response from CA.") print("Sending account information to the server.") username = request.data["username"] public_key = request.data["public_key"] ca_signature = request.data["signature"] request = Requests.create_new_account( username, public_key, ca_signature) private_key_b64 = base64.b64encode(self.private_key) enc_private_key, aes_iv = Crypto_Functions.aes_encrypt( str(private_key_b64), self.password_aes) enc_private_key_b64 = base64.b64encode(enc_private_key) aes_iv_b64 = base64.b64encode(aes_iv) tag_contents = str(enc_private_key_b64) + str( aes_iv_b64) hmac = Crypto_Functions.hmac_b64( tag_contents.encode(), self.password_hmac) hmac_b64 = hmac Database.add_user_account(self.username, str(enc_private_key_b64), str(aes_iv_b64), str(hmac_b64)) self.s.send(request) break elif request.is_ca_response_invalid(): print( "CA indicated an invalid request. Please try again with a different username." ) self.create_account() break # When we get to this point, we know CA sent back a valid response and that we sent a request # to the server to create an account. Now we wait for the server to send a confirmation that # the account has been created. while True: print("Waiting for the server...") data = self.s.recv(4096) request = Requests.parse_request(data) if len(request.data) == 0: print( "There was in issue with the received data. Received the following raw data: ", data) elif request.is_account_created(): print( "Account successfully created! Please log in with your new credentials." ) break elif request.is_account_not_created(): print("Account was not created. Please try again.") self.create_account() else: print( "The password you typed was not secure. Password must use letters and numbers and must be at least 8 characters." ) # When we get to this point, we know that the user's account has been created and we prompt the user to login # with their new credentials to proceed. self.login()
def test_generate_session_key(self): keys = {} for i in range(20): key = Crypto_Functions.generate_session_key() self.assertFalse(key in keys) keys[key] = None