Java: Is this a good use of BCrypt?

I would like to know if my current BCrypt implementation is correct, I know that I am not using BCrypt.checkpw() , which can lead to a problem, so this is the main reason I check 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()); } } 

Here's one problem: JPasswordField gives me char[] for security reasons, however BCrypt.hashpw() only accepts strings. How can I avoid String floating in my memory?

Client implementation of login:

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

So, the hash is sent over the network, currently the network is not encrypted, but I plan to add this.

Server implementation when creating an account:

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

Password Verification Server Implementation:

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

With this.hashedPassword a hash that resides in the server’s memory (which comes from the database at boot time).

Properties of my installation:

  • Logging into the system takes a considerable amount of time from the client, since the password is hashed there.
  • Creating an account / Changing the password takes a considerable time of the server, since then the password is hashed on the server.
  • When checking login attempts, the server practically does not require time, since hashing is not required.
  • If someone grabs a database containing hashes, then it will take some time to crack the password for each account.
  • I still need to find out a good performance factor for BCrypt.gensalt() .

Please check my assumptions.

Sincerely.

+4
source share
1 answer

There are a couple of problems with this setting.

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

2) This implementation does not actually verify the password provided by the client by checking the hash password provided by the client. This means that if someone gets your database of hashes, they can immediately use these hashes to log in. Then you do not need to crack them to extract passwords, since you do not check passwords.

Both of these problems can be easily resolved by moving the entire hash server side.

Update

Regarding the issues you mentioned.

1) If you intend to create a secure system, you must use SSL / TLS. Sending password hashes in a box is almost as unsafe as sending passwords to a box. Both are a terrible idea. Use HTTPS.

2) Server-side hashing is a fairly common practice. The hashing process is expensive enough to make an exhaustive search impractical, but it should not interfere with your authentication process. If you are really worried about DoSed, keep track of how many times a given user has tried to log in in the last N seconds. If they are not executed a certain number of times, block their account.

+10
source

Source: https://habr.com/ru/post/1481642/


All Articles