Spring security 使用BCryptPasswordEncoder时获取相同的哈希值

Spring security 使用BCryptPasswordEncoder时获取相同的哈希值,spring-security,bcrypt,Spring Security,Bcrypt,我使用的是使用BCryptPasswordEncoder的spring安全性。现在要更改密码,我需要做的是将用户提供的现有密码与DB值进行比较 public static String encodePassword(String password) { BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String hashedPassword = passwordEncoder.encode

我使用的是使用BCryptPasswordEncoder的spring安全性。现在要更改密码,我需要做的是将用户提供的现有密码与DB值进行比较

public static String encodePassword(String password) {
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String hashedPassword = passwordEncoder.encode(password);
    return hashedPassword;
} 
但由于salt是由
BCryptPasswordEncoder
动态生成的,所以每次我从下面的方法得到不同的散列值时,它不一定会与我的DB值匹配

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

这个问题有什么补救办法?我可以识别用于我的DB字段的salt,并在上述方法中使用相同的salt吗?

如果您使用具有自己属性(强度/随机)的BCryptPasswordEncoder和Spring MVC,那么您可以将您的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);;
} 

使用
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 
}

这是不对的。添加密码的全部意义在于,每次对密码进行编码时,都会使用不同的随机盐。Java类的实例有多少并不重要。是的,你是对的。我误解了这一点。但是,如果您指定自定义属性,那么使用单例密码编码器是一种很好的做法。