2014-11-07 33 views
11

Tôi đang sử dụng bảo mật mùa xuân bằng cách sử dụng BCryptPasswordEncoder. Bây giờ để thay đổi mật khẩu, những gì tôi cần làm là so sánh mật khẩu hiện tại được cung cấp bởi người dùng với giá trị DB.Nhận giá trị băm giống nhau khi sử dụng BCryptPasswordEncoder

Nhưng vì muối được tạo động bởi BCryptPasswordEncoder, mỗi khi tôi nhận được giá trị băm khác nhau từ phương thức dưới đây và không nhất thiết phải khớp với giá trị DB của tôi.

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

Biện pháp khắc phục cho vấn đề này là gì? thế nào tôi có thể xác định muối được sử dụng cho lĩnh vực DB của tôi và sử dụng cùng một muối trong phương pháp trên?

Trả lời

22

Sử dụng phương pháp matches trên giao diện PasswordEncoder để kiểm tra xem mật khẩu có giá trị, chứ không phải mã hóa nó một lần nữa và so sánh với băm hiện có.

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

Cảm ơn, đã thử điều này và làm việc như một say mê. – mms

1

Nếu bạn đang sử dụng BCryptPasswordEncoder với các thuộc tính của riêng bạn (sức mạnh/ngẫu nhiên) cùng với Spring MVC, thì bạn có thể khai báo PasswordEncoder của mình dưới dạng Bean. Bằng cách đó, nó sẽ là một trường hợp singleton và bạn có thể tái sử dụng nó.

Ở đây có một ví dụ (tôi không biết đó là cấu hình phong cách bạn đang sử dụng):

trong cấu hình bảo mật của bạn:

@Bean 
public PasswordEncoder passwordEncoder() { 

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

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

Tuy nhiên, trong điều khiển của bạn, bạn có thể so sánh mật khẩu như thế này :

@Autowired 
private PasswordEncoder passwordEncoder; 

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

Điều này không đúng. Toàn bộ điểm của muối là một muối ngẫu nhiên khác nhau được sử dụng mỗi khi bạn mã hóa mật khẩu. Nó không quan trọng bao nhiêu trường hợp của lớp Java có. –

+0

Có, bạn đã đúng. Tôi hiểu lầm điều này. Tuy nhiên, bằng cách sử dụng một PasswordEncoder singleton là một thực hành tốt nếu bạn chỉ định các thuộc tính tùy chỉnh. – Jonas

+0

Tôi đã sửa câu trả lời của tôi để phản ánh đề xuất của bạn. – Jonas

Các vấn đề liên quan