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_hash
和 password_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 推导中的熵非常低 - 这可能足以满足大多数目的,但不适用于高度安全的上下文。
我按照以下说明安装了邮件服务器: 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_hash
和 password_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 推导中的熵非常低 - 这可能足以满足大多数目的,但不适用于高度安全的上下文。