为什么BCrypt.net GenerateSalt(31)马上返回?
-
19-09-2019 - |
题
予跨越BCrypt.net偶然读取有关存储密码杰夫阿特伍德的讯息后一>这使我托马斯Ptacek的建议的使用BCrypt 来存储密码。这最终导致我的此C#实现BCrypt
在上面有人在最后一个环节评论中问道,“为什么GenerateSalt(30)采取永远,但GenerateSalt(31)似乎拿不出时间呢?”
我跑BCrypt.HashPassword(密码,BCrypt.GenerateSalt(31)),得到了我的结果在0毫秒。
我已经超过运行5分钟BCrypt.HashPassword( “密码”,BCrypt.GenerateSalt(30)),现在还没有结果。
我知道我们可能并不需要一个随机生成的30个字符的盐来创建我们的密码哈希值(或的在BCrypt的情况下不可逆加密)多年。的修改我应该读出的码位,logRounds不具有任何与所述盐的长度。感谢Aaronaught。
那么,为什么GenerateSalt(31)返回一个值几乎瞬间(当它应该大约两倍采取只要GenerateSalt(30)?
<强>更新强>
这里是修正:
private byte[] CryptRaw(byte[] password, byte[] salt, int logRounds) {
// ... snip ...
uint rounds = 1U << logRounds;
// ... snip
}
解决方案
我怀疑该错误是在这里:
private byte[] CryptRaw(byte[] password, byte[] salt, int logRounds) {
// ... snip ...
int rounds = 1 << logRounds;
// ... snip
}
当您为logRounds
指定31,它计算作为2 ^ 32,其不适合在int
和溢出,所以散列实际上完成在......呃,零张通行证。作者应该用uint
代替。很容易解决!
还希望对此发表评论:
我知道我们可能并不需要一个随机生成的30个字符盐来创建我们的密码哈希值...
请注意的是,logRounds
参数不是指字符数/中的盐,其是字节总是16.指通过散列将计算数的对数基;换句话说,它是一种方法,使摩尔定律bcrypt规模,使得功能幅度来计算,如果计算机永远得到足够快的速度来破解现有哈希更加昂贵几个数量级。
其他提示
如果有GenerateSalt(31)
散列返回几乎是瞬间,这是一个错误。你应该报告的上游(我有,对于jBCrypt)。 : - )
默认情况下,对数轮是10。这表示(如果我没有记错),1024发使用。每次递增日志回合时间,轮数增加一倍。
在30数回合,你在做1073741824发。这理所当然地需要很长的时间。在31数轮,两轮2147483648应该正在做,但我怀疑的是,具体的实现您正在使用溢出来代替。 : - (