Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting same hashed value while using BCryptPasswordEncoder

I am using spring security using BCryptPasswordEncoder. Now for change password what I need to do is to compare Existing Password provided by user with DB value.

But since salt is generated dynamically by BCryptPasswordEncoder, every time I get different hashed value from below method and not necessarily it would match with my DB value.

public static String encodePassword(String password) {
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String hashedPassword = passwordEncoder.encode(password);
    return hashedPassword;
} 

What's the remedy for this problem? can I identify salt used for my DB field and use the same salt in above method ?

like image 531
mms Avatar asked Nov 07 '14 23:11

mms


People also ask

Does bcrypt generate the same hash?

A BCrypt hash includes salt and as a result this algorithm returns different hashes for the same input.

Is bcrypt hash secure?

The takeaway is this: bcrypt is a secure algorithm but remember that it caps passwords at 72 bytes. You can either check if the passwords are the proper size, or opt to switch to argon2, where you'll have to set a password size limit.

Which Passwordencoders is recommended for production usage?

Password Encoding using BCryptPasswordEncoder The BCryptPasswordEncoder provides strength as a constructor argument to compute the hash. The larger value shows the longer time to hash but stronger password. We can also pass SecureRandom to randomize the generated hashes.

Is bcrypt a hash or encryption?

bcrypt is a password-hashing function designed by Niels Provos and David Mazières, based on the Blowfish cipher and presented at USENIX in 1999.


2 Answers

If you are using BCryptPasswordEncoder with your own properties (strength / random) together with Spring MVC, then you could declare your PasswordEncoder as a Bean. That way, it will be a singleton instance and you can reuse it.

Here comes an example (I don't know which configuration style you are using):

in your security configuration:

@Bean
public PasswordEncoder passwordEncoder() {

    int strength = // your strength;
    SecureRandom random = // your random

    PasswordEncoder encoder = new BCryptPasswordEncoder(strength, random);
    return encoder;
}

However, in your controller, you can compare passwords like this:

@Autowired
private PasswordEncoder passwordEncoder;

public boolean checkPassword(String password, String 
    return passwordEncoder.matches(password, hashedPassword);;
} 
like image 33
Jonas Avatar answered Oct 16 '22 20:10

Jonas


Use the matches method on the PasswordEncoder interface to check whether the password is valid, rather than encoding it again and comparing with the existing hash.

BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String existingPassword = ... // Password entered by user
String dbPassword       = ... // Load hashed DB password

if (passwordEncoder.matches(existingPassword, dbPassword)) {
    // Encode new password and store it
} else {
    // Report error 
}
like image 69
Shaun the Sheep Avatar answered Oct 16 '22 22:10

Shaun the Sheep