我应该用种子为我的 BCryptPasswordEncoder 初始化 SecureRandom 吗?

Should I initialize the SecureRandom for my BCryptPasswordEncoder with a seed?

我正在对同事的任务进行代码审查,发现了以下代码行(他正在实施一个 Spring 基于安全的登录系统)。

@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder(ENCODING_STRENGTH, new SecureRandom(SEED_BYTES));
}

用常量种子初始化这个特定的 SecureRandom 是个好主意吗?我不这么认为,但无法真正解释为什么。

参见SecureRandom

Additionally, SecureRandom must produce non-deterministic output. Therefore any seed material passed to a SecureRandom object must be unpredictable, and all SecureRandom output sequences must be cryptographically strong, as described in RFC 1750: Randomness Recommendations for Security.

如果你的SEED_BYTES是一个常数,它是可以预测的。

BCryptPasswordEncoder 使用密码学强度 SecureRandom 仅生成盐,参见 BCrypt#gensalt:

random - an instance of SecureRandom to use

这导致可预测的盐分。

盐应该(最多)是唯一的,请参阅 A Future-Adaptable Password Scheme:

As proposed by Morris and Thompson [9], however, lookup tables can be thwarted with the second input to F, which they call a salt. If a random salt is chosen whenever users establish new passwords, and if the salt space is large enough to ensure a negligible probability of recurrence, lookup tables offer an adversary no advantage; he may as well compute F at the time of attack. If, on the other hand, the salt space is too small, the output bits of F become useful predicates on passwords, a fact exploited by the QCrack [12] program described in Section 6.

如果您使用常量种子,您将在每次重新启动应用程序后获得相同的盐序列。这导致 salt collisions.

盐碰撞和可预测的盐会削弱您的安全性,请参阅Seven Ways To Screw Up BCrypt

#1: Using A Non-Random Salt

[...] If the salt for any two hashes is the same, then the attacker can re-use the computation to attack both at the same time (for brute force style attacks). [...]

#2: Using An Incorrect Random Source for Salt Generation

[...] Additionally, some of the weak random sources suffer from problems known as "seed poisoning" where an attacker can effect future generated randomness.