21

我正在为我的网站安装用户注册脚本 (Tank Auth)。

在安装指南中说,

警告:默认情况下,该库会生成不可移植的强系统特定密码哈希。这意味着一旦创建,用户数据库就不能转储并导出到另一台服务器。也可以在配置文件中更改此行为。

这让我进退两难。将来我可能想更改服务器,但我也不想要弱密码。便携式密码散列是否存在很大风险?更重要的是,它们所说的哈希是什么意思?是字符长度吗?

4

1 回答 1

95

Task Auth 使用 PHPass 进行密码散列(旧版本,这不是一个好兆头;您可能希望在安装中更新它)。PHPass 有两种模式,便携和 bcrypt。

根据 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 仍然会足够聪明地以正确的方式检查您的旧哈希值。

* 第 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-03-17T18:39:01.570 回答