4

我只是在对同事任务进行代码审查,并遇到了以下代码行(他正在实现基于 Spring Security 的登录系统)。

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

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

4

1 回答 1

6

SecureRandom

此外,SecureRandom 必须产生非确定性的输出。因此,传递给 SecureRandom 对象的任何种子材料都必须是不可预测的,并且所有 SecureRandom 输出序列必须具有加密强度,如RFC 1750: Randomness Recommendations for Security中所述。

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

BCryptPasswordEncoder仅使用加密强度SecureRandom来生成盐,请参阅BCrypt#gensalt

random - 要使用的 SecureRandom 实例

这导致了可预测的盐。

盐应该(充其量)是唯一的,请参阅A Future-Adaptable Password Scheme

然而,正如 Morris 和 Thompson [9] 所提出的,查找表可能会被 F 的第二个输入所阻碍,他们称之为盐。如果在用户建立新密码时选择随机盐,并且如果盐空间足够大以确保重复发生的概率可以忽略不计,那么查找表对对手没有任何优势;他也可以在攻击时计算 F。另一方面,如果盐空间太小,则 F 的输出位成为密码的有用谓词,第 6 节中描述的 QCrack [12] 程序利用了这一事实。

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

盐碰撞和可预测的盐会削弱您的安全性,请参阅搞砸 BCrypt 的七种方法

#1:使用非随机盐

[...] 如果任何两个哈希的盐值相同,那么攻击者可以重新使用计算来同时攻击两者(对于蛮力式攻击)。[...]

#2:使用不正确的随机源生成盐

[...] 此外,一些弱随机源遭受称为“种子中毒”的问题,攻击者可以影响未来生成的随机性。

于 2016-10-05T13:21:41.897 回答