password_hash如何真正起作用?

时间:2014-08-06 18:05:34

标签: php password-hash php-password-hash

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

根据我搜索的答案,我了解password_hash()函数是crypt()的包装器。在阅读predefined Constants的PHP手册时,我发现它使用PASSWORD_BCRYPT作为默认整数值(基本上它使用CRYPT_BLOWFISH算法来哈希密码)。

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

我的其他问题:

  • 为什么增加成本值会增加安全性?
  • 由于password_hash()是一种单向散列函数,password_verify()如何验证密码,因为盐是随机的?
  • 哈希值CRYPT_SHA512强于CRYPT_BLOWFISH吗?

3 个答案:

答案 0 :(得分:3)

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

  

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

是的它会 - 正如documentation所说,如果省略salt,则每个密码哈希值都会被password_hash()生成随机盐(这意味着如果省略options数组中的salt值,它将会默认情况下由password_hash()函数生成)。此外,自php 7.0以来,盐选项已被弃用

  

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

[{3>}在使密码破解更难:缓慢的哈希函数一节中也解释了这一点。设置成本越高,散列函数越慢。 这个想法是让散列函数非常慢,所以即使使用快速GPU或自定义硬件,字典和暴力攻击也太慢而不值得。但是成本应该设置为合理价值(根据您服务器的规格),以便在验证用户时不会造成重大的时间延迟。密码。

  

更多,CRYPT_SHA512对CRYPT_BLOWFISH的散列是否更强?

阅读有关比较的above article帖子。

答案 1 :(得分:2)

密码哈希基本上是在包装器中使用crypt()。它返回一个包含salt,cost和hash的字符串。它是一种单向算法,因为您不解密它来验证它,您只需使用您的密码传入原始字符串,如果它为所提供的密码生成相同的哈希值,则您需要进行身份验证。

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

成本(指数值)是指生成哈希需要多少努力(其中更高=生成哈希的计算能力更强)。不要将它设置得太高,否则你会忘记登录脚本。

答案 2 :(得分:1)

一般来说:

在散列密码时,您始终应该应用salt,即使您使用相同的密码,也要使用不同的散列。这可以通过“防止”人们使用彩虹表破解密码来提高安全性。

但是bcrypt自己处理盐腌!

回到原来的问题:

成本用于使用字典/暴力攻击破解密码“成本高昂”。

Bcrypt基本上会反复哈希密码,这使获取给定哈希的密码变得耗时(代价高昂)。如果您尝试为哈希(暴力攻击)找到密码,则必须计算数十亿个密码哈希值。当每次散列花费“$ cost”时间时,那么蛮力攻击是不可行的。即使你可以用毫秒计算潜在密码的哈希值。

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

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