Search code examples
springhashpasswordsencodebcrypt

Spring Boot Password Encoding


I am new to Spring boot and I am trying to configure the security for my api. I am using PasswordEncoding:

public static String encodePassword(String plainPassword){
    BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
    return bCryptPasswordEncoder.encode(plainPassword);
}

In the SecurityConfig class I got the following method:

@Bean
public PasswordEncoder getPasswordEncoder(){
    return new BCryptPasswordEncoder();
}

But each time given the same input the output is always different, can someone explain to me the reason behind this and how I can possibly fix this?


Solution

  • This is by design, there's nothing for you to "fix". The reason is because the BCrypt algorithm includes a salt, which will be different every time you call it. What this means is that if you're trying to encode a plain-text password to a hash and compare it to another hash, it's not going to match. You can, however, use the method, matches, in BCryptPasswordEncoder to compare.

    Here's a test that demonstrates this

    @Test
    public void encodeAndMatch() {
        BCryptPasswordEncoder bc = new BCryptPasswordEncoder();
    
        String p1 = bc.encode("password");
        String p2 = bc.encode("password");
        String p3 = bc.encode("password");
        
        assertNotEquals(p1, p2);
        assertNotEquals(p1, p3);
        assertNotEquals(p2, p3);
    
        assertTrue(bc.matches("password", p1));
        assertTrue(bc.matches("password", p2));
        assertTrue(bc.matches("password", p3));
    }
    

    Here you can see that the same password generated three distinct hashes, but the encoder can still compare the original plain-text password to each of them and match.