PHP password_verify真的安全吗?加另一种盐?

时间:2015-04-05 16:40:01

标签: php security encryption

我一直在阅读它是如何运作的,它在如何减缓暴力尝试方面真的很酷,但它仍然感觉不安全。

让我们说有人窃取了我的数据库数据,包括我的所有用户密码哈希值,并且知道我使用password_hash来哈希我的密码。他是否可以使用他的字典和password_verify循环访问我的密码以获取访问权限?

在散列密码之前添加另一个盐是一种好习惯吗?

3 个答案:

答案 0 :(得分:3)

不,如果有人偷了数据库,他们可能已经可以访问所有内容了,但是说他们没有,他们得到的只是哈希。

哈希不能在密码字段中使用,因为它会再次进行哈希处理并且与数据库中的哈希不匹配,需要实际密码,而不是哈希值。

使用password_verify并没有提供原始密码,它会检查密码是否与仅哈希匹配,这意味着您仍需要拥有原始密码哈希看看它们是否匹配,所以只有哈希才能让你无处可去。

$is_correct = password_verify($password_typed_by_user, $hash_gotten_from_db); // bool

在一天结束时,没有什么是安全的,哈希很可能会被蛮力,彩虹表或单词列表/词典等打破,但这无关紧要,因为它通常需要花费大量时间和努力,可以使用任何哈希,无论是否使用password_hash

使用更新的哈希和强密码是最好的防御,如果用于散列密码的算法有点慢,则循环遍历单词列表并散列每个单词需要更长的时间。同样,如果密码很长或者有特殊字符,则检查所有长度等字符需要更长的时间等。

添加更多盐无效。盐并不是一个秘密,它只是你添加的一个自定义的东西,以避免使用预先计算的查找表(如彩虹表)破解哈希。

salt通常与散列一起存储,或者在不同字段的同一个数据库中存储,或者当使用PHP password_hash时,它实际上只是连接到散列,看起来像mysalt.hash
一般来说,应该使用随机盐,以便不可能预先生成哈希表,并且这就是所需要的,盐不是秘密的,它不会添加除了使生成散列的函数有点独特之外的安全性,因此它不能大规模复制。

答案 1 :(得分:2)

添加@adeneo的答案,

bcrypt,pbkdf2,scrypt和现代密码哈希策略的重点是缓慢。

是的,如果从数据库(SQLi)获得结果哈希,您只需尝试密码并尝试验证每个密码。

然而,只是尝试密码有点轻描淡写。我们来看看一些数学。

使用bcrypt的password_hash()的默认费用大约需要0.1秒才能对密码进行哈希处理。这意味着验证密码哈希需要大约0.1秒。

英语中大约有1,000,000个单词。要尝试每一个,您需要验证1,000,000次。每秒0.1秒,即100,000秒(约27小时)。

对于泄露的单个密码哈希,1,000,000猜测为27小时。由于每个哈希都带有一个salt,攻击者需要为每个泄漏的哈希重复这些猜测。

如果您的数据库有100万用户,只需要针对密码尝试字典就需要76,000个CPU年(7,000个CPU,76,000年,76,000个CPU,1年,或之间的任何交易)。

从正确的角度来看,25 GPU cluster md5()可以做出每秒的180,000,000,000次猜测。为了从数据库中检查数百万个哈希的百万字典条目,需要大约5.5秒。

137 GPU-seconds与76,000 CPU-years。 是使用bcrypt的原因。

答案 2 :(得分:1)

这总是一个问题。我们希望您的用户使用的密码不在字典或前100个密码中。您有责任强制执行字典中不易找到的更强密码。