def __init__(self, remote_ip, remote_port, local_ip="0.0.0.0"): local_port = remote_port + 20 self.client = Client(remote_ip, remote_port) log( logging.info, self, self.__init__, "Connected on {}:{}".format(self.__class__.__name__, remote_ip, remote_port) ) self.server = Server(local_ip, local_port) log( logging.info, self, self.__init__, "Connected on {}:{}".format( self.__class__.__name__, local_ip, local_port) ) self._mutau_state = self.MUTUAL_AUTH_STATES[-1] self._session_key = None self._shared_key = None self._secret_value = random.randrange( 320, 1<<( crypto.BLOCK_SIZE*crypto.TO_BITS) )
def decrypt(key, ct): """Decrypts ciphertext ``ct`` with ``key``""" # Decompose the ciphertext ct, nonce, mac = ct[:-BLOCK_SIZE*2], ct[-BLOCK_SIZE*2:-BLOCK_SIZE], \ ct[-BLOCK_SIZE:] log( logging.info, __name__, decrypt, "\nct: {}\n" "nonce: {}\n" "mac: {}\n".format(ct, nonce, mac) ) # Check the MAC mac_key = derive_new_key(key) h = hmac.HMAC(mac_key, hashes.SHA256(), backend=BACKEND) h.update(ct + nonce) try : h.verify(mac) except: # This is just a hotfix so that the gui doesn't crash. # Idealy, the send and recv should have a header specifying # the number of bytes to send/receive raise DataIntegrityException() # Create the cipher with the extracted nonce cipher, _nonce = create_cipher(key, nonce=nonce) assert _nonce == nonce # Decrypt the plaintext decryptor = cipher.decryptor() pt = decryptor.update(ct) + decryptor.finalize() # Return the verified plaintext return pt
def send(self, msg): log( logging.info, self, self.send, msg ) self.conn.send(msg)
def recv(self): msg = self.conn.recv(self.BUFSIZE) log( logging.info, self, self.recv, msg ) return msg
def send(self, message): if self.authenticated == True: log( logging.info, self, self.send, "Encrypting message '{}'...".format( message, self._session_key ) ) ct = crypto.encrypt(self._session_key, message) log( logging.info, self, self.send, "Message encrypted to ciphertext: {}".format(ct)) log( logging.info, self, self.send, "Offering to send ciphertext..." ) self.client.send(ct) log( logging.info, self, self.send, "Ciphertext sent." ) else: raise NoAuthentication("No Authentication Established")
def on_server_btn_start(instance): btn_start.disabled = True txt_secret.readonly = True txt_port.readonly = True print_console("Starting Server on port " + txt_port.text) self.bob = None while self.bob is None: try: self.bob = ChatClientServer("0.0.0.0", int(txt_port.text)) except socket.error as e: log( logging.warning, self, self.make_server_tab, "Error occurred while trying to connect: " "socket.error: {}; retrying...".format(e), ) sleep(1) print_console("Setting shared key to " + txt_secret.text) self.bob.set_shared_key(txt_secret.text.encode())
def recv(self, nb=False): if self.authenticated == True: ct = self.server.recv() if not nb else self.server.nb_recv() if ct is None: return None log( logging.info, self, self.recv, "Ciphertext received: {}".format(ct) ) pt = crypto.decrypt(self._session_key, ct) log( logging.info, self, self.recv, "Ciphertext decrypted to: {}".format(pt) ) return pt else: raise NoAuthentication("No Authentication Established")
def __init__(self, local_ip="0.0.0.0", local_port=8051): # Start server first, then client (opposite order from ChatClientClient self.server = Server(local_ip, local_port) log( logging.info, self, self.__init__, "{}.server connected on {}:{}".format( self.__class__.__name__, local_ip, local_port)) remote_ip, _ = self.server.client_address remote_port = local_port + 20 self.client = Client(remote_ip, remote_port) log( logging.info, self, self.__init__, "{}.client connected on {}:{}".format( self.__class__.__name__, remote_ip, remote_port)) self._mutau_state = self.MUTUAL_AUTH_STATES[-1] self._secret_value = random.randrange( 320, 1<<( crypto.BLOCK_SIZE*crypto.TO_BITS) )
def on_client_btn_start(instance): if is_valid_ip(txt_ip.text): btn_start.disabled = True txt_secret.readonly = True txt_port.readonly = True txt_ip.readonly = True print_console("Starting Client on port " + txt_port.text) self.alice = None while self.alice is None: try: self.alice = ChatClientClient(txt_ip.text, int(txt_port.text)) except socket.error as e: log( logging.warning, self, self.make_client_tab, "Error occurred while trying to connect: " "socket.error: {}; retrying...".format(e), ) sleep(1) print_console("Setting shared key to " + txt_secret.text) self.alice.set_shared_key(txt_secret.text.encode()) else: print_console("Please enter a valid IP address")
def mutauth_step(self, reset=False): if reset: self._mutau_state = self.MUTUAL_AUTH_STATES[-1] return if self._shared_key is None: raise NoSharedKey("Shared key is not setup yet. Can't proceed") if self._mutau_state == self.MUTUAL_AUTH_STATES[-1]: log( logging.info, self, self.mutauth_step, "server receive client's ra" ) self._Ra = self.server.recv() self._mutau_state = self.MUTUAL_AUTH_STATES[0] elif self._mutau_state == self.MUTUAL_AUTH_STATES[0]: # Send response: RB, E("Bob", RA, gb mod p, KAB) self._Rb = os.urandom(crypto.BLOCK_SIZE) gb_mod_p = pow(self._g, self._secret_value, self._p) pt = self._identifier + self._Ra + str(gb_mod_p) ct = crypto.encrypt(self._shared_key, pt) msg = self._Rb + ct self.client.send(msg) log( logging.info, self, self.mutauth_step, "server sends rb + its identifier, rb, and gb mod p" ) self._mutau_state = self.MUTUAL_AUTH_STATES[1] elif self._mutau_state == self.MUTUAL_AUTH_STATES[1]: # Receive E("Alice", RB, ga mod p, KAB) ct = self.server.recv() pt = crypto.decrypt(self._shared_key, ct) identifier, rb, ga_mod_p = self.extract_auth_msg_parts(pt) log( logging.info, self, self.mutauth_step, "server receives client's identifier, rb, and ga mod p" ) if rb != self._Rb: raise BeingAttacked("Trudy is attacking") if identifier == self._identifier: raise BeingAttacked("Trudy is doing replay attack") self._session_key = pow(long(ga_mod_p), self._secret_value, self._p) log( logging.info, self, self.mutauth_step, "server creates the session key" ) self._mutau_state = self.MUTUAL_AUTH_STATES[2] self._session_key = crypto.derive_new_key(str(self._session_key)) elif self._mutau_state == self.MUTUAL_AUTH_STATES[2]: raise StopIteration("Authentication completed successfully.")
def mutauth_step(self, reset=False): """This method steps through mutual authentication and key exchange using Diffie-Helman Each call to this method will perform one step out of the total steps necessary for authentication :param bool reset: If this is set, we reset back to step -1 """ if reset: self._mutau_state = self.MUTUAL_AUTH_STATES[-1] return if self._shared_key is None: raise NoSharedKey("Shared key is not setup yet. Can't proceed") if self._mutau_state == self.MUTUAL_AUTH_STATES[-1]: # Send our public key (Ra) self._Ra = os.urandom(crypto.BLOCK_SIZE) self.client.send(self._Ra) log( logging.info, self, self.mutauth_step, "Client sends Ra" ) self._mutau_state = self.MUTUAL_AUTH_STATES[0] elif self._mutau_state == self.MUTUAL_AUTH_STATES[0]: # Get response: RB, E("Bob", RA, gb mod p, KAB) resp = self.server.recv() self._rb = resp[:crypto.BLOCK_SIZE] log( logging.info, self, self.mutauth_step, "client receives rb" ) ct = resp[crypto.BLOCK_SIZE:] pt = crypto.decrypt(self._shared_key, ct) self._server_ident, ra, gb_mod_p = self.extract_auth_msg_parts(pt) log( logging.info, self, self.mutauth_step, "client receives identifier of server, ra, and gb mod p" ) if ra != self._Ra: raise BeingAttacked("Trudy is attacking") self._session_key = pow(long(gb_mod_p), self._secret_value, self._p) log( logging.info, self, self.mutauth_step, "client creates the session key" ) self._mutau_state = self.MUTUAL_AUTH_STATES[1] elif self._mutau_state == self.MUTUAL_AUTH_STATES[1]: # Send E("Alice", RB, ga mod p, KAB) # Client identifier can be anything other the the server's ident identifier = os.urandom(crypto.BLOCK_SIZE) while identifier == self._server_ident: identifier = os.urandom(crypto.BLOCK_SIZE) log( logging.info, self, self.mutauth_step, "client creates its identifier that's not the same as server's" ) ga_mod_p = pow(self._g, self._secret_value, self._p) log( logging.info, self, self.mutauth_step, "client creates ga mod p" ) pt = identifier + self._rb + str(ga_mod_p) log( logging.info, self, self.mutauth_step, "client sends its identifier, the server's rb, and ga mod p" ) ct = crypto.encrypt(self._shared_key, pt) self.client.send(ct) self._mutau_state = self.MUTUAL_AUTH_STATES[2] self._session_key = crypto.derive_new_key(str(self._session_key)) elif self._mutau_state == self.MUTUAL_AUTH_STATES[2]: raise StopIteration("Authentication completed successfully.")