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 ?
A BCrypt hash includes salt and as a result this algorithm returns different hashes for the same input.
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.
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.
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.
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);;
}
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With