I need to communicate over an insecure TCP sockets where SSL/TLS is not available. Does the following solution provide a secure means of authentication and encryption? 1. **Client sends: username** 1. Server generates a random token (30 bytes). 1. Server retrieves a password salt and hash (bcrypt) from the database for the given username. 1. Server encrypts the random token by the password hash. 1. **Client receives: passwordSalt + encryptAes(token, passwordHash)** 1. Client gets the passwordHash by using bcrypt on the password and the received password salt. 1. Client gets the token by decrypting the encrypted token by the password hash. 1. Client generates a random 'validation' salt (16 bytes). 1. Client generates a hash of the token using the validation salt. 1. **Client sends: validationSalt + bcrypt(token, validationSalt)** 1. Server compares if the received hash is equal to bcrypt(token, validationSalt). If they are the same, the client has authenticated. 1. Server generates a hash of the password hash using the validation salt. 1. **Client receives: bcrypt(passwordHash, validationSalt)** 1. Client compares the hash with bcrypt(passwordHash, validationSalt). If they are the same, the server has authenticated. All data will now be encrypted with the token generated by the server. - The server is in Java, the clients are in C++ (UE4). Public key encryption is currently not available. - Is there any flaw or weakness in this solution?