当前位置: 首页 > 知识库问答 >
问题:

密码散列是如何工作的?

詹杰
2023-03-14

我试图完全理解密码散列,以便能够向审计员解释它。

基于我对答案的搜索,我知道password_hash()函数是Crypt()的包装器。在阅读预定义常量的PHP手册时,我看到它使用PASSWORD_BCRYPT作为默认整数值(基本上它使用CRYPT_BLOWFISH算法来散列密码)。

让我困惑的是,$options变量如果省略,会生成一个随机salt,并且成本将设置为10。如果我提供了更高的成本(例如:12),由于我没有提供salt值,它还会生成随机salt吗?我在这里感到困惑的原因是,我没有忽略$options,而是提供了不同的成本。

我的其他问题:

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

共有3个答案

芮建茗
2023-03-14

一般来说:

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

但是bcrypt自己处理盐渍!

回到你最初的问题:

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

Bcrypt基本上是反复散列密码,这使得获取给定散列的密码非常耗时(=昂贵)。如果您试图为哈希(暴力攻击)查找密码,则必须计算数十亿个密码哈希。如果每次哈希花费的“$cost”时间是原来的两倍,那么暴力攻击是不可行的。即使您可以在毫秒内计算潜在密码的哈希值。

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

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

顾高翰
2023-03-14

密码散列的工作原理是在包装器中使用crypt()。它返回一个字符串,其中包含salt、cost和hash。这是一种单向算法,因为您不需要解密来验证它,只需将原始字符串与密码一起传递,如果它为提供的密码生成相同的哈希,则您将通过身份验证。

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

成本(指数值)指的是生成哈希的工作量(其中更高=生成哈希的计算能力更多)。不要把它设置得太高,否则你会让你的登录脚本停滞不前。

裴彦
2023-03-14

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

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

是的,它会-正如文档所述,如果省略salt,则密码\u hash()将为每个经过哈希处理的密码生成一个随机salt(这意味着如果您从选项数组中省略salt值,它将默认由密码\u hash()函数生成)。此外,自PHP7.0以来,salt选项已被弃用。

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

在上面的文章“使密码破解更加困难:慢速散列函数”一节中也解释了这一点。成本设置得越高,哈希函数的速度就越慢。这样做的目的是使哈希函数非常慢,因此即使使用快速GPU或自定义硬件,字典和暴力攻击也太慢,不值得。但是,成本应该设置为合理的值(基于服务器的规格),以便在验证用户密码时不会造成明显的时间延迟。

还有,CRYPT_SHA512比CRYPT_河豚更强壮吗?

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

 类似资料:
  • 问题内容: 我需要对密码进行哈希处理以存储在数据库中。如何用Java做到这一点? 我希望使用纯文本密码,添加随机盐,然后将盐和哈希密码存储在数据库中。 然后,当用户想要登录时,我可以使用其提交的密码,从其帐户信息中添加随机盐,对其进行哈希处理,然后查看其是否等同于其帐户信息所存储的哈希密码。 问题答案: 实际上,你可以使用Java运行时内置的工具来执行此操作。Java 6中的SunJCE支持PBK

  • 我正在为拉拉维尔创建一个散列密码。现在有人告诉我使用Laravel哈希助手,但我似乎找不到它,或者我找错了方向。 如何创建laravel散列密码?在哪呢? 编辑:我知道代码是什么,但我不知道在哪里和如何使用它,所以它返回给我散列密码。如果得到散列密码,就可以手动将其插入数据库

  • 我试图理解Maven 3的[password encryption(密码加密)功能。我发现这个功能的文档记录很差,令人困惑。例如,功能文档和该功能作者的博客文章在几个方面相互矛盾。 这个问题比maven-encrypt master password如何工作更广泛,maven encrypt master password选择密码的良好实践没有涵盖。 具体来说,我试图回答以下文件中未涉及的问题。我

  • 我认为我理解散列和加盐密码,但似乎我有一些误解。我在nodejs为我的网站创建一个用户帐户系统。 我的理解是,当用户创建密码时,我们会生成一个随机盐,将其附加到密码中,然后散列该字符串。我们还可以添加一个工作因子以使散列工作缓慢并防御蛮力攻击。我们将盐与散列一起存储在我们的数据库中,为了验证登录尝试,我们使用存储的盐和尝试的密码重复上述过程(在服务器上),并检查散列是否匹配。 nodejs中的模块

  • 我正在处理一个pet项目,现在我想添加用户注册支持。经过一些研究,我决定在数据库中保存哈希密码和salt,而不是原始密码。然而,我不知道这些步骤是什么,顺序是什么。以下是我的假设: 注册 客户端向服务器发送用户名和密码(https) 服务器获取密码,生成随机salt Base64对盐进行编码 用stringify salt散列密码 Base64对密码进行编码 将密码和salt保存到数据库中 登录

  • 我一直在阅读OWASP10,我遇到了存储信息的最佳实践。咸杂碎。在这里,您为每个密码生成一个随机的salt,并对其进行梳理、散列和存储。我的疑问是,如果salt是随机生成的,当用户键入密码时,如何对密码进行身份验证?salt是否与用户名一起保存?如果是这样,这种做法仍然是脆弱的。或者他们是怎么做到的?