Dovecot SHA512-Crypt 和 PHP

Dovecot SHA512-Crypt and PHP

我按照以下说明安装了邮件服务器: http://www.geoffstratton.com/ubuntu-mail-server-postfix-dovecot-and-mysql

现在我正尝试在 PHP 中编写登录表单,但不知道如何将输入的密码与保存的密码进行比较。

这是密码加密的 mysql 代码:

ENCRYPT('PASSWORD', CONCAT('$', SUBSTRING(SHA(RAND()), -16)))

我不明白它是如何工作的,因为每次调用这个函数都会生成一个全新的字符串。

这是我目前拥有的:

crypt($_POST[‘password’], '$'.substr(sha1(rand()), 0, 16))

但就像我每次得到一个新字符串时所说的那样。

使用 PHP 函数 password_hashpassword_verify。 这些函数加盐并迭代以提供安全保护。

参见PHP手册password_hash and password-verify

string password_hash ( string $password , integer $algo [, array $options ] )

Returns 散列密码,失败时为 FALSE。

boolean password_verify ( string $password , string $hash )

Returns 如果密码和哈希匹配则为 TRUE,否则为 FALSE。

示例代码:

$hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT)

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

在您的情况下,您从数据库中获取该用户名的密码哈希,并将其保存在名为 $hash 的变量中。然后你像这样使用 password_verify()

password_verify($_POST["password"], $hash)

考虑将密码简单地存储为其散列的情况。任何阅读数据的人都很难弄清楚密码到底是什么,但这并非不可能,确实有在线数据库包含大量索引哈希和相应的明文 - 可以简单地查找常用密码的哈希。此外,考虑两个用户具有相同哈希值的情况 - 这也意味着任何读取数据的人都会知道他们具有相同的密码。

这两个问题都在安全系统上通过向明文添加随机字符串(称为 salt)来解决。此盐仅生成一次,然后与密码一起存储。

所以你存储的数据是$6$[salt]$[(salt + password)的哈希值]

要验证密码,您使用存储的盐和提供的密码重新创建哈希,并将其与存储的哈希进行比较。 crypt 函数会忽略 salt 之后的任何数据,因此您只需这样做:

if ($stored === crypt($_REQUEST['password'], $stored)) {
    // Password is valid

您使用的代码在其 salt 推导中的熵非常低 - 这可能足以满足大多数目的,但不适用于高度安全的上下文。