我正在为我的网站安装用户注册脚本 (Tank Auth)。
在安装指南中说,
警告:默认情况下,该库会生成不可移植的强系统特定密码哈希。这意味着一旦创建,用户数据库就不能转储并导出到另一台服务器。也可以在配置文件中更改此行为。
这让我进退两难。将来我可能想更改服务器,但我也不想要弱密码。便携式密码散列是否存在很大风险?更重要的是,它们所说的哈希是什么意思?是字符长度吗?
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 编码版本。
$final = '$P$'
$final .= encode64_int($rounds)
(来自构造函数,PHP 5+ 上的最小值为 5,其他为 3)
$final .= genSalt()
(盐是 6 个字节......“encode64”格式的 8 个字节)。
$hash = md5($salt . $password)
2
$rounds
有时,做$hash = md5($hash . $password)
$final = encode64($hash)
所以最终的哈希基本上是这样的:
$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0
\__________/\____________________/
\ \
\ \ Actual Hash
\
\ $P$ 9 IQRaTwmf
\_/ \ \______/
\ \ \
\ \ \ Salt
\ \
\ \ # Rounds (not decimal representation, 9 is actually 11)
\
\ Hash Header