Search code examples
javasslniojava-securitysslengine

NIO Client / server securely authenticate credentials


I use Java NIO secured by SSL to connect client and server. To connect to a server the user is prompted to enter host, port, username and password. So far I can connect client and server (they successfully complete their SSL handshake) and I could theoretically start sending data back and forth. I have not written a mechanism to verify login credentials (username, password) yet.

The server can authenticate username and password by looking them up in a database. If the credentials a client sends are incorrect, the connection will be closed.

Question 1: When should the credentials be validated? I assume this has to happen after the SSL handshake.

Question 2: How do I securely package the credentials before they are serialized and sent to the server? I assume I should hash the password. Should I hash the username too?

Would something simple like this suffice?

public class LoginCredentials implements Serializable {

    private static final long serialVersionUID = 1026410425432118798L;

    private final String username;
    private final byte[] passwordHash;

    public LoginCredentials(String username, byte[] passwordHash) {
        this.username = username;
        this.passwordHash = passwordHash;
    }

    public final String getUsername() {
        return username;
    }

    public final byte[] getPasswordHash() {
        return passwordHash;
    }

}

Question 3: Authenticating credentials should be done once per session, correct? I read some posts that seemed to indicate the credentials should be verified for every request.

Question 4: Which hashing algorithm should I use? SHA–512 seems to be very popular.


Solution

    1. of course that after ssl handshake, when the ssl connection is established, this makes it more secure
    2. Not many applications really do that, most of them just sends the password over ssl not hashing it at all. Yes, you can generate a hash, but the hash should be generated for every login, so it will not be always the same, this requires some code on client side to resolve some challenge which includes the correct password and some random thing sent by server, otherwise it would not differ much from regular password authentication. But there is plenty of authentication mechanisms - passwords, hashes, tokens, ssl certificates to name a few.
    3. you need to check if the authenticated user has access rights to the resource He tries to access - this is for every request, not to login the user for every request if you have session. If you need to manage the user access rights to grant or revoke access during single session then you need to read the user access rights for every request, if you don't need such granularity then reading them once for the whole session is ok. Sometimes there are sessionless services eg. some REST, then typically you need to send some credentials on every call.
    4. You can use any hashing algorithm that's not too easy to decipher.