1

我试图完全理解password_hash,以便能够为审计员解释它。

根据我对答案的搜索,我了解到该password_hash()函数是crypt(). 在阅读预定义常量的 PHP 手册时,我看到它PASSWORD_BCRYPT用作默认整数值(基本上它使用CRYPT_BLOWFISH算法来散列密码)。

令我困惑的是$options,如果省略该变量,则会生成一个随机盐,并且成本将设置为10. 如果我提供更高的成本(例如:)12,它是否仍会生成随机盐,因为我没有提供盐值?我在这里感到困惑的原因是因为我没有省略,$options而是提供了不同的成本。

我的其他问题:

  • 为什么增加成本价值会增加安全性?
  • 由于盐是随机的,既然password_hash()是单向散列函数,如何验证密码?password_verify()
  • CRYPT_SHA512CRYPT_BLOWFISH散列强吗?
4

3 回答 3

4

我发现这篇文章对于理解如何正确散列密码非常有用。它解释了如果散列很弱,如何使用各种技术破解散列,以及如何正确散列密码以提供足够的安全性。

如果我提供更高的成本(比如 12),它是否仍会生成随机盐,因为我没有提供盐值

是的 - 正如文档所说,如果省略 salt,password_hash() 将为每个散列密码生成一个随机盐(这意味着如果您从选项数组中省略 salt 值,它将由 password_hash() 函数生成默认)。此外,自 php 7.0 起, salt 选项已被弃用

为什么增加成本价值增加安全性?

上述文章中的使密码破解更难:慢散列函数一节中也对此进行了解释。成本设置得越高,散列函数越慢。这个想法是让哈希函数变得非常慢,这样即使使用快速的 GPU 或自定义硬件,字典和暴力攻击也太慢了,不值得。然而,成本应该设置为合理的值(基于您的服务器的规格),以便在验证用户密码时不会导致明显的时间延迟。

更多,CRYPT_SHA512 是否比 CRYPT_BLOWFISH 更强大?

阅读这篇关于他们比较的文章。

于 2017-02-25T11:51:31.180 回答
2

密码哈希通过使用crypt()基本上是一个包装器来工作。它返回一个包含盐、成本和哈希的字符串。这是一种单向算法,因为您无需对其进行解密以对其进行验证,您只需将原始字符串与您的密码一起传递,如果它为所提供的密码生成相同的哈希值,则您已通过身份验证。

最好省略盐,让它为你生成一个。如果您只使用一种盐,则更容易破解所有密码,而不仅仅是那个密码。无论成本如何,都可以生成盐。

成本(指数值)是指生成散列所付出的努力(其中越高 = 生成散列的计算能力越强)。不要将其设置得太高,否则您会陷入登录脚本的困境。

于 2014-08-06T18:13:11.100 回答
1

通常来说,一般来说:

在对密码进行哈希处理时,您始终应该使用盐,即使您使用相同的密码也可以使用不同的哈希值。这通过“防止”人们使用彩虹表来破解密码来提高安全性。

但是 bcrypt 自己处理盐渍!

回到你原来的问题:

该成本用于使使用字典/蛮力攻击破解密码变得“昂贵”。

Bcrypt 基本上一遍又一遍地对密码进行哈希处理,这使得获取给定哈希的密码非常耗时(=成本高昂)。如果您尝试为哈希查找密码(蛮力攻击),则必须计算数十亿个密码哈希。当每个散列花费“$cost”倍的时间时,暴力攻击是不可行的。即使您可以以毫秒为单位计算出潜在密码的哈希值。

简单来说:如果你有一个 SHA-1 的密码散列(不安全,不要使用它!)和盐(因为这通常包含在散列中)并且你想破解它,那么你必须对所有可能的散列密码+盐,当您找到具有相同哈希的组合时,您找到了该哈希的可能密码。

假设您使用了一个好的盐和足够长的密码,那么密码哈希需要 1-5 秒。如果您使用 cost=10 的河豚方法,则密码哈希需要 10-50 秒。对于单个密码,这没什么大不了的。所以针对单个哈希的定向攻击仍然很简单,但通常人们会获得大量用户和密码组合列表,并且他们有兴趣快速获取所有这些组合的密码。那么这对坏人来说就没有那么有利可图了,因为他需要 10 倍的 CPU 能力来计算所有这些东西。

于 2014-08-30T08:25:26.617 回答