1

I'm creating a basic register/login username/password database and I'm wondering if my approach is correct. I'm not satisfied with code just working, I want it to be clean and efficient as well.

Users can access an internet login page, enter credentials, and basically log in. I have a Database class, which creates accounts and checks if the credentials entered are correct.

So, the Database class:

public class Database {

    private Connection          connection          = null;
    private PreparedStatement   preparedStatement   = null;
    private ResultSet           resultSet           = null;

    // Method for registering a new account. Credentials are added into the database.
    public void registerAccount(String username, String password, String ipAddress) {

        try {

            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
            connection = DriverManager
            .getConnection("jdbc:derby:C:\\DB;create=true;upgrade=true");
            String query = "INSERT INTO Users (username, password, ip_address) VALUES" + "(?,?,?)";
            preparedStatement = connection.prepareStatement(query);
            preparedStatement.setString(1, username);
            preparedStatement.setString(2, password);
            preparedStatement.setString(3, ipAddress);
            preparedStatement.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close();
        }

    }

    private void close() {

        try {

            if (resultSet != null) {
                resultSet.close();
            }
            if (preparedStatement != null) {
                preparedStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

e.g.: When a user clicks submit to log in, a method inside the Database class is called:

// Checks if credetials are correct.
public boolean checkLogin(String username, String password) {

    try {

        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        connection = DriverManager
                .getConnection("jdbc:derby:C:\\DB;create=true;upgrade=true");
        String query = "SELECT username, password from Users WHERE username = ? AND password = ?";
        preparedStatement = connection.prepareStatement(query);
        preparedStatement.setString(1, username);
        preparedStatement.setString(2, password);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            String user = resultSet.getString("username");
            String pass = resultSet.getString("password");
            if (username.equalsIgnoreCase(user)) {
                if (password.equals(pass)) {
                    return true;
                }
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        close();
    }
    return false;
}

I also have a few other methods in the Database class to check if username is not taken when registering, or if an account is already registered on a particular IP, etc. Is this good practice or there are better, more efficient ways of achieving this? Thank you!

PM 77-1
  • 12,933
  • 21
  • 68
  • 111
  • Well pretty good to me. Although, since this is a web system I would suggest you to take a look into security frameworks like [Spring Security](http://projects.spring.io/spring-security/) and delegate such responsability to an already well documented framework. On your code I would suggest only some hash technique so you hash the user password and insert it, when you will check you hash the string sent by the user and compare as you are doing. That way even you couldn't see a user password. – Jorge Campos Jan 09 '16 at 02:58

1 Answers1

0

Query the record through the username to get the ecrypted password, and compare it to the ecrypted password from user input.

Here is a reference How can I hash a password in Java?. PBKDF2 is a good algorithm for password hashing.

byte[] salt = new byte[16];
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 128);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = f.generateSecret(spec).getEncoded();
Base64.Encoder enc = Base64.getEncoder();
System.out.printf("salt: %s%n", enc.encodeToString(salt));
System.out.printf("hash: %s%n", enc.encodeToString(hash));

Here is the PBKDF2 one in python. It's easy for you to get the idea.

Community
  • 1
  • 1
caot
  • 3,066
  • 35
  • 37
  • I'm not sure i know how to do that. could you provide a short example or a place where i could do some reading? – user2342352 Jan 09 '16 at 03:12
  • 1. Spring Security Crypto Module @ https://docs.spring.io/spring-security/site/docs/3.1.7.RELEASE/reference/crypto.html ; 2. How to add PBKDF2 password hashing to a Spring Security based project @ http://www.michalklempa.com/2015/02/08/how-to-add-pbkdf2-password-hashing-to-a-spring-security-based-project/ – caot Jan 11 '16 at 20:47