【问题标题】:Is PHP password_verify really secure? Add another salt?PHP password_verify 真的安全吗?再加盐?
【发布时间】:2015-06-10 03:53:34
【问题描述】:

我一直在阅读它的工作原理,它在减慢暴力破解尝试方面确实很酷,但它仍然感觉不安全。

假设有人窃取了我的数据库数据,包括我所有的用户密码哈希,并且知道我使用password_hash 对我的密码进行哈希处理。难道他不能用他的字典和password_verify 遍历我的密码来获得访问权限吗?

在对密码进行哈希处理之前添加另一种盐是一种好习惯吗?

【问题讨论】:

    标签: php security encryption


    【解决方案1】:

    补充@adeneo的答案,

    bcrypt、pbkdf2、scrypt 和现代密码散列策略的要点是要慢。

    是的,如果您从数据库 (SQLi) 获得生成的哈希值,您可以尝试输入密码并尝试验证每个密码。

    但是,只需尝试密码 有点轻描淡写。让我们看一些数学。

    password_hash() 与 bcrypt 的默认成本大约需要 0.1 秒来散列密码。这意味着验证密码哈希大约需要 0.1 秒。

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

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

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

    从角度来看,25 GPU cluster 上的 md5()每秒可以进行大约 180,000,000,000 次猜测。要将这百万个字典条目与数据库中的百万个哈希值进行对比,大约需要 5.5 秒。

    137 GPU 秒与 76,000 CPU 年。 就是使用 bcrypt 的原因。

    【讨论】:

      【解决方案2】:

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

      哈希不能用于密码字段,因为它会再次被哈希并且与数据库中的哈希不匹配,需要实际的密码,而不是哈希。

      使用password_verify 不会为您提供原始密码,它只会检查密码是否与哈希匹配,这意味着您仍然必须拥有原始密码哈希才能看看它们是否匹配,所以只有散列会让你无处可去。

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

      归根结底,没有什么是安全的,哈希很可能会被暴力破解、彩虹表或单词列表/字典等破坏。但这无关紧要,因为它通常需要大量时间和精力,而且可能无论是否使用password_hash,都使用任何哈希完成。

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

      添加更多的盐没有任何作用。盐不是秘密,它只是您添加的自定义内容,以避免哈希值被预先计算的查找表(如彩虹表)破解。

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

      【讨论】:

      • 如果他本地有hash和字典,他就不能用password_verify来检查猜测的密码是否等于hash? - 在散列之前添加额外的盐会改善它吗?
      • 他可以,但是对于任何存储哈希和盐的系统都可以这样说,如果密码不在字典中,它就会失败。换句话说,拥有好的词典和强大的计算机能力可以加快破解密码的速度。长密码不包含常用单词、短语和密码,还包含大量字符,会减慢密码破解过程。
      【解决方案3】:

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

      【讨论】:

      • 只有一种方法可以创建强密码:1. 打开您的编辑器 2. 在键盘上敲击头部 1-3 次就可以了 :)
      • 在服务器端添加另一种盐会改善这一点吗?
      • @KhalidAl-Mutawa 仅当该盐存储在其他地方并且攻击者也无法窃取该盐时。
      • 盐不是秘密,也不应该是秘密,主要是为了让彩虹表和预先计算的哈希几乎不可能进行攻击。
      • @Rizier123 开个玩笑(不是真的),如果你有一个尖头,那么你就不会按下足够长的键来使密码足够长。另一方面,如果你的头是扁平的,你就会遇到问题,因为它还会敲击相邻的键,而这些模式可能会被密码破解者利用。
      猜你喜欢
      • 1970-01-01
      • 2016-09-18
      • 2019-01-19
      • 2012-07-05
      • 2016-05-04
      • 2014-06-23
      • 1970-01-01
      • 2012-06-12
      • 2010-09-06
      相关资源
      最近更新 更多