4

打开“portable_hashes”。我注意到无论出于何种原因,它生成的哈希值并不总是相同的 - 但在通过“CheckPassword”传递时总是返回有效。我还注意到在生成哈希时使用了“PHP_VERSION”——这两件事结合起来让我很担心……便携性如何?我可以在服务器、linux、windows、64 位、32 位等之间移动哈希(保存在用户数据库中)吗?仍然让它们验证吗?我该怎么做才能使密码不再有效?

我问的原因是因为我在我的框架中使用 phpass 作为密码,这将为我的几个网站提供动力,其中许多网站目前有数千名用户 - 在某些情况下我不得不将它们移动到不同的服务器上,当然还有升级php。我也可以将其中的一两个从 Apache 切换到 lighthttpd 或类似的东西。不用说我非常偏执,有一天我会做一个支持噩梦,除了通过电子邮件将新密码发送给每个人(这听起来很不安全)之外,我将无法以任何其他方式解决它。

如果密码被设为无效的可能性很小 - 我必须采取哪些步骤来制作自己的密码哈希生成器?我已经使用了 16 字节随机盐(每用户),除此之外,唯一的另一个问题是拉伸 - 对吗?

4

2 回答 2

8

根据 PHP 版本,您不需要启用可移植哈希。在 PHP 5.3 及更高版本上,如果系统上不可用,PHP 会提供自己的 bcrypt 实现。如果你所有的服务器都有 PHP 5.3 及更高版本,我强烈建议关闭便携式哈希。PHPass“便携式哈希”之所以存在,是因为根据安装的 PHP 版本,bcrypt 可能不可用。

也就是说,PHPass 可移植哈希确实将盐存储在其哈希中。这就是为什么每次使用相同的密码运行都是不同的。

此外,PHPassPHP_VERSION在生成这些哈希时使用*来检查md5()该版本可用的函数是否支持该$rawMode参数。如果没有,pack()则用于将十六进制数据转换为二进制(请注意,这比简单地使用要慢得多$rawMode,这就是创建分支的原因)。

同样,如果您的所有服务器都运行 PHP 5.3 及更高版本,我强烈建议关闭便携模式并让 PHPass 使用bcrypt。由于 PHP 5.3+ 在系统不可用时提供了自己的实现,因此您的哈希将可以跨操作系统检查。即使您确实关闭了便携模式,PHPass 仍然会足够聪明地以正确的方式检查您的旧哈希值。

我和你的情况一样,在我的框架中跨多个站点使用 PHPass。由于我关闭了便携模式,我已将我的登录脚本设置为逐步重新散列未在登录时使用 bcrypt 的密码。

* 第 131 行


编辑:更多解释,这里是如何生成可移植模式的哈希(简化,不使用 PHPass 中的实际变量,但准确)。请注意,PHPPass 使用他们自己的 base64 编码版本。

  1. $final = '$P$'

  2. $final .= encode64_int($rounds) (来自构造函数,PHP 5+ 上的最小值为 5,其他为 3)

  3. $final .= genSalt()(盐是 6 个字节......“encode64”格式的 8 个字节)。

  4. $hash = md5($salt . $password)

  5. 2$rounds有时,做$hash = md5($hash . $password)

  6. $final = encode64($hash)

所以最终的哈希基本上是这样的:

$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0
\__________/\____________________/
  \                   \
   \                   \ Actual Hash
    \
     \  $P$   9   IQRaTwmf
        \_/   \   \______/
         \     \      \
          \     \      \ Salt
           \     \ 
            \     \ # Rounds (not decimal representation, 9 is actually 11)
             \
              \ Hash Header
于 2011-01-25T03:31:52.877 回答
1

我能看到的唯一用途PHP_VERSION是在这一行:

$output .= $this->itoa64[min($this->iteration_count_log2 +
    ((PHP_VERSION >= '5') ? 5 : 3), 30)];

现在,所有这一切都是确定最大迭代次数。它是在gensalt_private产生盐的方法中。所以这只会在存储新密码和生成盐时发生。所以之前生成的所有盐都是 100% 可移植的。所以根本没有真正的可移植性问题......

至于其余的,只要您使用的是相当新的 php 版本(5.0+),据我所知,您根本不应该有任何可移植性问题(因为该hash函数是内置的).. .

于 2011-01-25T01:45:32.830 回答