Java: Is this good use of BCrypt?

China☆狼群 提交于 2019-12-22 09:46:26

问题


I would like to know if my current implementation of BCrypt is correct, I am aware that I am not using BCrypt.checkpw() which may lead to an issue so that is the main reason I verify it here.

Hasher.java container class:

abstract public class Hasher {
    public static String hash(final char[] input) {   
        String output = Hasher.hash(new String(input));
        for (int i = 0; i < input.length; i++) {
            input[i] = 0;
        }
        return output;
    }

    public static String hash(final String input) {
        return BCrypt.hashpw(input, BCrypt.gensalt());
    }
}

One concern here: JPasswordField gives me a char[] for security reasons, however BCrypt.hashpw() only accepts Strings. How can I avoid that String from floating around in my memory?

The client implementation of logging in:

String hashedPassword = Hasher.hash(password);
Network.getInstance().send("login " + username + " " + hashedPassword);

So the hash gets sent over the network, currently the network is not encrypted but I plan on adding that.

The server implementation on account creation:

public static Account createAccount(final String username, final String password) {
    String hashedPassword = Hasher.hash(password.toCharArray());
    return new Account(username, hashedPassword);
}

The server implementation of checking password:

public boolean checkPassword(final String hashedPassword) {
    return this.hashedPassword.equals(hashedPassword);
}

With this.hashedPassword being the hash that is in the server's memory (which comes from a database on bootup).

Properties of my setup:

  • Logging in takes the client significant time, as the password is hashed there.
  • Creating an account/Changing password takes the server significant time, as the password is hashed on the server then.
  • Validating login attempts takes the server practically no time, as no hashing needs to be done.
  • If someone gets hold of the database containing the hashes, then it will take him significant time to crack the password per account.
  • I still need to figure out a good work factor for the BCrypt.gensalt().

Please verify my assumptions.

Regards.


回答1:


There are a couple problems with this setup.

1) The salt should be a value randomly generated during the hashing process (as it seems to be in your implementation. Since the client does not have access to the database of stored hashes, the client will not know what salt to use when creating a login hash.

2) This implementation is not actually checking the password passed by the client, it's checking the password hash passed by the client. That means that if someone gets your database of hashes, they can immediately use those hashes to login. Then do not need to crack them to extract passwords, since you do not check the passwords.

Both these issues can be easily solved by moving all hashing server side.

Update

Regarding the issues you mentioned.

1) If you have any intention of creating a secure system, you should be using SSL/TLS. Sending password hashes in the clear is almost as totally insecure as sending passwords in the clear. Both are a terrible idea. Use HTTPS.

2) Performing server side hashing is a pretty ordinary practice. The hashing process is computationally expensive enough to make exhaustive search impractical, but it shouldn't hinder your authentication workflow. If you're really concerned about being DoSed, keep track of how many times a given user has tried to login in the last N seconds. If they've failed a certain number of times, lock their account.



来源:https://stackoverflow.com/questions/16636711/java-is-this-good-use-of-bcrypt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!