【问题标题】:Using blowfish in PHP for storing passwords在 PHP 中使用河豚来存储密码
【发布时间】:2013-02-06 03:41:08
【问题描述】:

整个密码学的内容令人难以接受,但它真的很有趣,我最近一直在阅读它。

我的问题是关于使用河豚来散列密码以进行存储。我知道需要盐,但我不确定该怎么做。我有一些问题。

  1. 我读过的许多教程,人们似乎只是随机地提出了一个像“oidsjf03”这样的教程,并将它用于他们所有的盐。他们只是捣碎键盘还是什么?

  2. 我也读过很多文章说每个密码都应该有一个唯一的哈希值。所以我为我存储的每个密码生成一个单独的盐。然后我必须把它存储在某个地方。然而在哪里?如果我只是将它作为一个条目存储在用户的行中,如果数据库遭到破坏,他们是否不能只使用该盐生成彩虹表?

    我是否正确地说这是不可行的,因为他们需要为每个密码生成一个彩虹表,并且使用河豚创建每个哈希需要一段时间,所以这不实用?

  3. 为什么为每个用户拥有一个独一无二的用户如此重要?假设您正在使用河豚,并且您的数据库遭到破坏,并且您的盐也被捕获。黑客可以创建一个彩虹表来测试您的密码,但是如果对哈希进行大量轮次,例如,每个密码可能需要 0.1 秒。如果他们想创建一个包含 10 亿个条目的彩虹表,那么创建它需要 1 亿秒(或大约 3 年)。

    如果您使用独特的盐并设置 1000 个密码,他们将不得不创建 1000 个彩虹表,将时间增加到 3000 年。这是为什么?每个存储密码的时间会增加吗?

  4. 如何为哈希生成这个盐? PHP 的uniqid() 功能够不够,还是我应该做一些花哨的事情?

  5. 我真的需要创建一个完整的类等,还是可以创建一个简单的函数?

  6. 最后,我听说 phpass 提到了很多关于它的安全性以及用户应该如何使用它而不是自己可能会出错。这真的是推荐的做法吗?

【问题讨论】:

  • Re: #3,盐应该对每个用户分开的原因是,如果多个用户使用相同的密码(“secret1”),他们将不会有相同的哈希 - 攻击者可以'不要告诉他们都使用相同的密码,他们将不得不单独破解每个密码。回复:#6,是的。安全的基本规则是,最好使用其他人编写并经过许多其他人测试过的代码,而不是从头开始并重复他们的错误。

标签: php mysql hash passwords blowfish


【解决方案1】:

1- 我读过的许多教程似乎只是随机地提出了一个像“oidsjf03”这样的教程,并将它用于他们所有的盐。他们只是捣碎键盘还是什么?

对所有东西都使用相同的盐是个坏主意。期间。

2- 我也读过很多文章说每个密码都应该有一个唯一的哈希值。所以我为我存储的每个密码生成一个单独的盐。然后我必须把它存储在某个地方。然而在哪里?如果我只是将它作为一个条目存储在用户的行中,如果数据库被破坏,他们难道不能用那个盐生成彩虹表吗?

盐是哈希的一部分。只有当您有多个使用相同盐的用户时,彩虹表才有效。但它们都是独一无二的,对吧?因此,将其与哈希一起存储就可以了。 #3 也是如此。

4- 你如何为哈希生成这个盐? PHP 的uniqid() 函数够用吗?还是我应该做一些花哨的事情?

从 PHP 5.5 开始,password hashing functions 已直接内置到 PHP 中。同时,请参阅上述链接,在 cmets 中是一个 Github 项目的链接,该项目与这些功能向前兼容并且适用于 PHP >= 5.3.7。

6- 最后,我听说 phpass 提到了很多关于它的安全性以及用户应该如何使用它而不是自己可能会出错。这真的是推荐的做法吗?

内置的 PHP 函数更好,因为一旦发现任何安全漏洞,它们将始终保持最新状态。我会改用它们。但是 phpass 是一个很好的选择。

【讨论】:

【解决方案2】:

除了上述答案之外,您还可以在数据库中使用哈希值保存盐,因为如果您的数据库被入侵,攻击者需要知道您的盐算法。比如 hash($pass.$salt) 或 hash(hash($pass).$salt) 等。

【讨论】:

  • 我正在使用河豚,所以我只需要散列一次,可以这么说。但是散列密码中不是散列的次数吗? $2x$07 或其他,7 是哈希值。
  • 我实际上不同意这一点。为了根据哈希验证密码,您需要使用完全相同的参数重新哈希密码。因此需要存储所有内容,包括使用的算法、盐、轮数等。如果您使用crypt,则所有内容都存储在计算字符串中(算法、成本参数、盐和实际散列细绳)。秘诀是使用足够多的轮数/成本,以使暴力破解需要很长的时间,但对最终用户来说却很短(例如~250 ms)。
  • @DougSmith 最好使用$2y$,而不是$2x$。是的,07 部分是两位数的成本参数,它必须在0431 之间。我们的想法是在不给用户带来不便的情况下将其保持在尽可能高的水平。当然,这将取决于计算它的硬件。我目前将我的设置为12,计算大约需要 250 毫秒,但如果您的服务器功能较弱,您可能希望将其设置为 1011 或更多,如果它更强大或者如果您宁愿花更长的时间来计算哈希值。
  • @Mike 我只是在谈论即使 DB 被盗(使用哈希和盐)通常更难窃取程序文件。因此,攻击者仍然不知道哈希算法及其参数。因此,我们不需要将盐保存在比密码或其他地方更安全的地方。
  • @Yaroslav,我认为如果有人能够窃取您的数据库文件,他们很可能也可以访问您程序的源代码,这是一个公平的假设。然而,即使他们不这样做,这也存在一个巨大的问题 - 如果您的散列参数存储在源代码中,那么您将被锁定为永远只使用这些参数。您可能有一天会升级您的服务器硬件并决定现在可以使用$2y$13$ 代替$2y$10$,但您将无法这样做,因为参数未存储在散列中,而是存储在程序的源代码中.
猜你喜欢
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
相关资源
最近更新 更多