PHP的password_verify函数真的安全吗?需要再加一层盐吗?

3
我一直在了解它的工作原理,它真的很酷,因为它可以减缓暴力破解尝试,但它仍然不够安全。
比如说,如果有人窃取了我的数据库数据,包括所有用户密码哈希值,并知道我使用password_hash来哈希我的密码。那么他不能只是通过字典循环遍历我的密码并使用password_verify来获取访问权限吗?
在哈希密码之前添加另一个盐是否是好的做法?
3个回答

4
不,如果有人窃取了数据库,他们可能已经可以访问到所有内容,但是假设他们没有,他们只会得到哈希值。
哈希值不能在密码字段中使用,因为它会再次被哈希化,不匹配数据库中的哈希值,一个人需要实际密码,而不是哈希值。
使用 password_verify 并不能提供原始密码,它仅检查密码是否与哈希值匹配,这意味着您仍然需要拥有原始密码和哈希值才能确定它们是否匹配,因此仅有哈希值无法获得任何信息。
$is_correct = password_verify($password_typed_by_user, $hash_gotten_from_db); // bool

最终来说,没有什么是绝对安全的。使用暴力破解、彩虹表或者密码字典等工具可以破解哈希值,但这一点并不重要,因为无论是否使用了“password_hash”,这些方法都需要耗费大量时间和精力才能完成。
使用更新的哈希算法和强密码是最好的防御措施。如果用于哈希密码的算法比较慢,那么检查每个单词所需的时间就会更长。同样,如果密码比较长或包含特殊字符,则需要更长的时间才能检查到该长度的所有字符。
添加更多盐并没有什么作用。盐并不是机密信息,只是一种自定义的东西,可避免使用预先计算的查找表(如彩虹表)破解哈希值。
通常,盐与哈希值一起存储,可以存储在同一数据库的不同字段中,也可以在使用PHP的“password_hash”时直接将其连接到哈希值上,形成类似“mysalt.hash”的格式。一般来说,应使用随机盐,使得预先生成哈希表变得不可能。除此之外,盐并不能为函数生成哈希提供额外的安全保障,它只是使得哈希函数变得有些独特,从而无法大规模复制。

如果他本地同时拥有哈希和字典,他无法直接使用password_verify来检查猜测的密码是否等于哈希值吗?- 在哈希之前添加额外的盐会改善它吗? - Khalid Al-Mutawa
他可以这样做,但任何存储哈希和盐的系统都可能如此,如果密码不在字典中,它将失败。换句话说,拥有良好的字典和大量的计算机能力可以加速破解密码。使用不包含常见单词、短语和密码的长密码,同时包含大量字符,可以减缓破解密码的过程。 - adeneo

4

在@adeneo的回答中,需要补充说明的是:

bcrypt、pbkdf2、scrypt以及现代密码哈希策略的关键在于它们效率很低。

如果你从数据库中得到了结果哈希值(通过SQLi),那么你可以简单地尝试各种密码并验证每个密码。

不过,“尝试各种密码”这个说法有点轻描淡写。我们来看一下具体的数字。

使用bcrypt默认设置的 password_hash() 方法,对一个密码进行哈希大约需要0.1秒钟的时间,也就是说验证一个密码哈希大约需要0.1秒钟的时间。

英语中大约有1,000,000个单词。要逐个验证每个单词,你需要验证1,000,000次。每次验证需要0.1秒钟,那么总共需要100,000秒钟(约27小时)。

对于一个泄漏的单个密码哈希值,所需时间为27小时,用来尝试1,000,000种密码组合。由于每个哈希值都附带一个盐值,攻击者需要对每个泄漏的哈希值都重复尝试这些密码组合。

如果你的数据库中有1,000,000个用户,则尝试将字典中的密码与数据库中的密码进行匹配将需要76,000个CPU年(其中一个CPU使用76,000年,或者76,000个CPU使用1年,或者任何其他组合)。

更具体地说,md5()一台25个GPU的计算机集群上可以每秒执行约1800亿次哈希验证。要对来自数据库的1,000,000个哈希值进行一百万个字典条目的验证,大约需要5.5秒钟。

137个GPU秒与76,000个CPU年相比。这就是为什么使用bcrypt的原因。


2

这是一个普遍的问题。希望您的用户使用的密码不在字典或常用密码的前100个中。您有责任强制实施更加安全的密码,以确保其不易被破解。


1
创建一个强密码只有一种方法:1. 打开你的编辑器 2. 在键盘上敲击头部1-3次,然后你就可以开始了 :) - Rizier123
在服务器端添加另一个盐值会改善这个问题吗? - Khalid Al-Mutawa
@KhalidAl-Mutawa 只有当盐值存储在其他地方且攻击者无法窃取时,才能这样做。 - Artjom B.
盐值并不是一个秘密,也不应该是。它的作用主要是使得使用彩虹表和预先计算的哈希攻击变得几乎不可能。 - adeneo
1
开玩笑(其实不是),如果你的头很尖,那么你敲击键盘的次数就不够,无法使密码足够长。另一方面,如果你的头很扁,你会遇到一个问题,因为你也会敲击相邻的键,这些模式可以被密码破解器利用。 - Artjom B.
“盐”是一个合理的密码存储方案所需的最低要求,但它并不一定能构建一个安全的密码存储方案。 - John McMahon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接