2014-11-07 7 views
11

BCryptPasswordEncoder를 사용하여 스프링 보안을 사용하고 있습니다. 이제 비밀번호 변경을 위해 사용자가 제공 한 Existing Password와 DB 값을 비교해야합니다.BCryptPasswordEncoder를 사용하는 동안 동일한 해시 값 가져 오기

그러나 소금은 동적으로 BCryptPasswordEncoder에 의해 생성되므로 아래의 메서드에서 다른 해시 값을 얻을 때마다 반드시 내 DB 값과 일치하지는 않습니다.

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

이 문제의 해결책은 무엇입니까? DB 필드에 사용 된 소금을 식별하고 위의 방법에서 같은 소금을 사용할 수 있습니까?

답변

22

확인하기 위해 PasswordEncoder 인터페이스에서 matches 방법을 사용 다시 기존 해시와 비교합니다.

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 
} 
+0

고마워, 이것을 시도하고 매력처럼 일했다. – mms

1

BCryptPasswordEncoder를 Spring MVC와 함께 자신의 속성 (strength/random)과 함께 사용하는 경우 PasswordEncoder를 Bean으로 선언 할 수 있습니다. 그렇게하면 싱글 톤 인스턴스가되며 재사용 할 수 있습니다. 보안 구성

:

@Bean 
public PasswordEncoder passwordEncoder() { 

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

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

그러나, 컨트롤러에서,이 같은 암호를 비교할 수 있습니다 여기에

는 예 (난 당신이 사용하고있는 구성 스타일을 모르는를) 제공 : 암호가 유효보다는 인코딩 여부

@Autowired 
private PasswordEncoder passwordEncoder; 

public boolean checkPassword(String password, String 
    return passwordEncoder.matches(password, hashedPassword);; 
} 
+0

이것은 올바르지 않습니다. 소금을 적시는 요지는 암호를 인코딩 할 때마다 다른 무작위 소금이 사용된다는 것입니다. Java 클래스의 인스턴스가 몇 개인가는 중요하지 않습니다. –

+0

네, 맞습니다. 나는 이것을 오해했다. 그러나 사용자 지정 속성을 지정하면 Singleton PasswordEncoder를 사용하는 것이 좋습니다. – Jonas

+0

귀하의 제안을 반영하여 답변을 수정했습니다. – Jonas

관련 문제