为了安全地哈希密码,我应该使用哪种算法?BCrypt
还是PBKDF2WithHmacSHA1
?
哪个更安全?PBKDF2WithHmacSHA1
内置于Java中,而BCrypt
可通过jBCrypt库获得(该库大多获得正面评价)。
此外,如果我使用BCrypt
,我是否应该将用户的密码输入限制为仅55个字符(因为这是BCrypt
的限制)?
如果您是Java
的特定用户,这将非常有帮助
请注意,我会选择让密码更安全、暴力强制更困难的选项。
它们不一样,也不同样安全。
在CPU上,它们使用的资源量大致相同,在保护密码方面也大致相同。
问题归结为基于GPU的攻击。由于GPU的体系结构,bcrypt实际上比SHA1(或SHA256)更难运行。因此,PBKDF2+sha1的并行化比bcrypt更容易。
为了在上面加上一些实际的数字,我们将从这个演示文稿中提取。
Sha-1的价格大约是md5的3倍。因此,如果我们看一下慢散列函数幻灯片,我们可以得出结论,md5crypt比pbkdf2-sha1快大约3倍。这是一个相当多的猜测,但它在我们所寻找的范围内。
这意味着,对于一个均衡的CPU运行时,我们可以预期PBKDF2-sha1在GPU集群上每秒运行大约2500万个哈希。与BCrypt(成本为5)相比,BCrypt每秒运行7.5万个哈希。
因此,这意味着在同等成本设置下,PBKDF2+sha1比bcrypt弱大约1000倍。
不过请注意,PBDFK2+sha512的速度几乎和bcrypt一样慢。这与使用64位操作的SHA-512有关(这些操作在今天的GPU中不是本机操作)。
简而言之,bcrypt比PBKDF2+SHA1安全几个数量级。它比PBKDF2+SHA512更安全,但没有那么大的优势。
这依赖于今天的GPU架构。将来,如果缓存大小和指令集发生显著变化,这些差异可能会消失。这就是为什么像scrypt这样的新算法存在的原因。
所以只需使用bcrypt。不要担心字符限制
这其实并不重要
他们两人的安全性差异不足以做出有意义的选择。如果你正在寻找一个彻底的讨论,尽管,看看尤金的评论中的两个链接
重要的是你正确地对待他们
这意味着:
- 选择正确的成本因素/迭代次数。如果你是彻底的,你会想基准测试你的服务器可以容忍多慢的哈希函数。越慢(=成本因素/迭代次数越高)越好。为了给你一个大概的数字,我的全磁盘加密软件已经确定,带有HmacSHA1的PBKDF2需要大约10000次迭代才能运行50ms
- 正确使用salt:每个密码都需要一个随机值(salt),您将其存储在哈希旁边,并用作每次哈希的输入。不要在每个密码中使用相同的盐,那将是胡椒粉,很好,但不能代替盐
- 以可升级的方式存储您的密码。稍后,一旦哈希方案被广泛接受,您可能需要更改成本因素或添加胡椒值,或将其更改为scrypt。为了实现这一点,数据库条目需要告知使用哪个参数选择来生成密码。例如,请参阅此常用的unix密码存储格式
"如果我使用BCrypt,我是否应该将用户的密码输入限制为仅55个字符(因为这是BCrypt的限制)?"
没有。使用SHA1或SHA256对密码进行一次哈希运算,然后像以前使用密码一样使用输出。如果你想涂胡椒粉,这就是你的选择。最后,如果这听起来很麻烦,这可能是使用PBKDF2而不是bcrypt的决定因素。