代码之家  ›  专栏  ›  技术社区  ›  B. Reiter

Dovecot SHA512地穴和PHP

  •  0
  • B. Reiter  · 技术社区  · 8 年前

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

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

    这是密码加密的mysql代码:

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

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

    这就是我目前掌握的:

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

    但正如我所说,每次我得到一根新绳子。

    2 回复  |  直到 8 年前
        1
  •  0
  •   Vicente Olivert Riera    8 年前

    使用PHP函数 password_hash password_verify . 这些功能具有salt和iterate功能,可提供安全保护。

    参见PHP手册 password_hash password-verify .

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

    返回散列密码,失败时返回FALSE。

    boolean password_verify ( string $password , string $hash )
    

    如果密码和哈希匹配,则返回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)

        2
  •  0
  •   symcbean    8 年前

    考虑这样的情况,密码只是作为其哈希存储。任何阅读数据的人都会很难弄清楚密码到底是什么,但这并非不可能,事实上,在线数据库包含大量索引哈希和相应的明文——只需查找常用密码的哈希即可。此外,如果两个用户有相同的散列,也就是说任何读取数据的人都会知道他们有相同的密码。

    这两个问题都是通过添加随机字符串(称为 salt 到明文。这个salt只生成一次,然后与密码一起存储。

    因此,您存储的数据是$6$[salt]$[hash of(salt+password)]

    为了验证密码,您可以使用存储的salt和提供的密码重新创建哈希,并将其与存储的哈希进行比较。crypt函数忽略salt之后的任何数据,因此只需执行以下操作:

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

    您正在使用的代码在其salt派生中具有非常低的熵-这可能适合大多数用途,但在高度安全的上下文中不适用。