我一直在阅读它是如何运作的,它在如何减缓暴力尝试方面真的很酷,但它仍然感觉不安全。
让我们说有人窃取了我的数据库数据,包括我的所有用户密码哈希值,并且知道我使用password_hash
来哈希我的密码。他是否可以使用他的字典和password_verify
循环访问我的密码以获取访问权限?
在散列密码之前添加另一个盐是一种好习惯吗?
答案 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个密码中。您有责任强制执行字典中不易找到的更强密码。