我正在将Spring Security的Bcrypt密码编码器集成到一个新的应用程序中,在测试时我注意到,当使用两个具有不同工作因素的编码器匹配密码时,工作负载似乎没有效果。请看以下示例:
public static void main(String[] args) {
PasswordEncoder strongEncoder = new BCryptPasswordEncoder(12);
PasswordEncoder weakEncoder = new BCryptPasswordEncoder(6);
String password = "SomePassword@@";
String strongEncodedPass = strongEncoder.encode(password);
String weakEncodedPass = weakEncoder.encode(password);
//Prints true
System.out.println(weakEncoder.matches(password, strongEncodedPass));
//Prints true
System.out.println(strongEncoder.matches(password, weakEncodedPass));
}
由于编码器使用不同的工作负载,两个打印语句都不应该导致错误吗?
使用Java 8中的spring-security-core-4.1.0.RELEASE.jar测试上述示例
答案 0 :(得分:2)
如果你看一下有关BCrypt(https://en.wikipedia.org/wiki/Bcrypt)的维基百科文章,你会注意到哈希的格式包含轮数
例如,影子密码记录
$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
指定成本参数10,表示210次密钥扩展轮次。盐是N9qo8uLOickgx2ZMRZoMye,结果哈希是IjZAgcfl7p92ldGxad68LJZdL17lhWy。
因此,当密码与哈希匹配时,它会被散列与原始哈希的次数相似。
换句话说:matches()
与设置无关,可能是静态的......
答案 1 :(得分:0)
阅读源代码时,仅在生成salt时使用强度。加密算法本身使用的轮数被硬编码为16。
所以你看到的是预期的。不知道为什么Spring不允许为加密部分选择多个回合。在错误/功能请求中,可能值得发出信号,因为文档确实令人困惑。