BCryptPasswordEncoder影响服务器的启动时间

时间:2017-04-06 15:38:25

标签: spring-boot spring-security

为什么BCryptPasswordEncoder的强度会影响服务器的启动时间?启动时没有生成哈希,所以我想知道为什么这会对启动产生任何影响。

当然,我知道检查密码是否匹配需要时间,但在启动时很奇怪。

代码如下所示:

@Bean
public BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(17); // Affects startup time tremendously
}

@Autowired
BCryptPasswordEncoder bcryptEncoder;

@Autowired
CustomUserDetailsService userDetailsService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService)
      .passwordEncoder(bcryptEncoder);
}

3 个答案:

答案 0 :(得分:1)

(取决于您的配置)
看看春天DaoAuthenticationProvider 启动时调用以下方法:

private void setPasswordEncoder(PasswordEncoder passwordEncoder) {
  Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
  this.userNotFoundEncodedPassword = passwordEncoder.encodePassword(
      USER_NOT_FOUND_PASSWORD, null);
  this.passwordEncoder = passwordEncoder;
}

这是因为服务器有一个编码密码来验证密码,而不是尝试进行身份验证的用户名不存在。

/**
 * The plaintext password used to perform
 * {@link PasswordEncoder#isPasswordValid(String, String, Object)} on when the user is
 * not found to avoid SEC-2056.
 */
private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";

参见:
https://github.com/spring-projects/spring-security/issues/2280
https://jira.spring.io/browse/SEC-2056

注意:如果您将强度设置为17并且您的服务器需要额外的5分钟才能启动,那么在进行身份验证时,您的服务器将花费大约5分钟来验证每个用户的密码。

答案 1 :(得分:0)

issue现在已解决,因此如有必要,请升级Spring Boot / Spring Security。

Spring Security会调用PasswordEncoder.matches()而不管是否找到了该用户,从而使黑客无法通过比较响应时间来检测该用户是否存在。为了为不存在的用户创建虚拟的加密密码或哈希,Spring Security调用一次PasswordEncoder.encode("userNotFoundEncodedPassword")并重用结果。该调用以前是在启动过程中进行的,但是现在在第一次需要时会被懒惰地调用。

答案 2 :(得分:-1)

BCryptPasswordEncoder的构造函数在启动时没有做任何事情,具体取决于密码强度:

public BCryptPasswordEncoder(int strength) {
    this(strength, null);
}

public BCryptPasswordEncoder(int strength, SecureRandom random) {
    if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) {
        throw new IllegalArgumentException("Bad strength");
    }
    this.strength = strength;
    this.random = random;
}

看过这个,我不认为只改变强度参数会增加启动时间,如上所述。

但是当你真正使用加密器时,'强度'肯定会影响性能。那你可能在启动时在某处加密了许多密码?