【问题标题】:I don't understand how password_verify works (PDO)? Please explain [duplicate]我不明白 password_verify 是如何工作的(PDO)?请解释[重复]
【发布时间】:2019-06-15 06:14:26
【问题描述】:

我得到了这个任务,直到现在,我一直在使用 sha1 来保证安全。 上周五老师给我们回了电话,告诉我们使用password_hash。 知道它是为明天准备的,我试图弄清楚它是如何工作的,但不要绕着它转。 我发现很多人都在谈论它,但这些都不适合我: How to use password_hash Register And Login

目前,由于它被分配,我只使用 PDO 并返回到我以前的工作代码(使用 sha1)

    <?php
    ob_start();// TEST
    include("inc/timer.inc.php");//session
    require("inc/database.inc.php");//connection website
    $title='website';

    if (isset($_POST['formConnection'])) {
    $loginConnection = filter_input(INPUT_POST, 'loginConnection', FILTER_SANITIZE_FULL_SPECIAL_CHARS   );

    // Connection sha1- OLD
    $passwordConnection = sha1($_POST['passwordConnection']);

    // Connection password_hash
    //$hash = $profile['password'];
    //$passwordConnection = password_verify($_POST['passwordConnection'], $hash);

        if (!empty(($loginConnection) AND !empty($passwordConnection))) {
            $connection = $website->prepare("SELECT * FROM members WHERE login = ? AND password= ?");
            $connection->execute(array($loginConnection, $passwordConnection));
            $userExists = $connection->rowCount(); //Test existence et affectation à la session des valeurs

            if ($userExists == 1) {
            $profile = $connection->fetch();
            $_SESSION['idMember'] = $profile['idMember'];
            $_SESSION['login'] = $profile['login'];
            $_SESSION['status'] = $profile['status'];
            header("Location: member-detail.php?idMember=".$_SESSION['idMember']);
            } else {
            echo "<script>alert(\"Wrong login or password\")</script>"; 
            }

        } else {
        echo "<script>alert(\"Please check your login or your password\")</script>"; 
        }

    }
    ?>
    <body>

        <form method="post" action="">

            <div class="form-group">
                <label for="loginConnection">login</label><br>
                <input type="text" class="form-control" name="loginConnection" id="loginConnection"
                    placeholder="login" required><br><br>
            </div>

            <div class="form-group">
                <label for="passwordConnection">password</label><br>
                <input type="password" class="form-control" name="passwordConnection" id="passwordConnection"
                    placeholder="Mot de Passe" required><br><br>
            </div>
            <input type="submit" name="formConnection" value="Se connecter">

            <div class="form-group">
                <a href="subscribe.php">Not subscribed yet?</a>
            </div>

        </form>
        <br><br>

    </body>

我知道它应该是一个布尔值,但我不知道如何使用它。

有这方面的分步教程吗?我可能错过了。 谢谢

【问题讨论】:

  • 我投票结束您的问题作为重复,因为它太宽泛并且已经多次回答过,即使在 PHP 手册本身中也是如此。但是,如果您有一个有效的问题/错误,您可以编辑您的问题并专注于一个问题。我们很乐意提供帮助。
  • 首先通过登录(不使用密码)从数据库中提取用户数据,然后从数据库中获取哈希值并将其与password_verify 的表单输入进行比较。将哈希与数据库查询进行比较实际上是不安全的,仅举一个例子:数据库搜索在 MySQL 中(通常)不区分大小写,但哈希是。因此,由于大小写,您可能有 2 个哈希值发生冲突(被视为相同)。
  • 这可能看起来微不足道,但请考虑暴力破解密码时的影响。现在,不是一个在 sha1 中匹配的哈希,而是超过 2^40(我认为,无论如何它比 1 多得多)匹配,只是因为大小写问题。

标签: php mysql sql pdo password-hash


【解决方案1】:

您必须从数据库中获取用户,然后使用password_verify 检查密码。因此,只需SELECT * FROM members WHERE login = ?,然后在您的if ($userExists == 1) { 内部,如果password_verify($_POST['passwordConnection'], $profile['password') 为假,则登录失败。

【讨论】:

    【解决方案2】:

    password_verify() 函数将与password_hash() 函数结合使用。

    您将password_hash() 生成的哈希存储在您的数据库中。当有人尝试登录时,您可以根据哈希值测试他们提供的密码。如果password_verify() 返回 true,则密码匹配。

    您不应该使用password_hash() 自己重新设置密码,因为you will get a different answer every time(如果使用随机盐,您应该这样做)。当您使用password_hash() 对密码进行哈希处理时,默认情况下,它使用随机盐对其进行哈希处理。这个随机盐被编码到生成的散列字符串中,以便password_verify() 可以使用与最初散列相同的盐来验证它。

    基本上,您应该从数据库中为尝试登录的用户检索哈希值,并将其提供给password_verify() 函数。除了盐,散列还包含有关使用哪种散列算法的信息。

    php.net example

    <?php
    // See the password_hash() example to see where this came from.
    $hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
    
    if (password_verify('rasmuslerdorf', $hash)) {
        echo 'Password is valid!';
    } else {
        echo 'Invalid password.';
    }
    ?>
    

    【讨论】:

    • 您从 SO 复制了另一个答案。我们在这里不这样做。如果已经有可用的答案,我们将作为副本关闭。
    • 嗯?我从头开始写,减去复制示例
    • 您觉得您的答案比您复制的其他答案更好吗?甚至代码中的注释也没有意义,因为您复制了另一个答案的一小部分。
    • 实际上,这是 PHP 自己网站上唯一的一个完整示例。php.net/manual/en/function.password-verify.php,所以你现在可以收回你的反对票了,拜托
    • 如果您想让答案变得更好,您可以改进答案。包括如何使用 password_hash 的示例,添加 PHP 手册的链接,指出 OP 在选择查询中使用密码字段,警告他们 VARCHAR 的最小长度。目前你的答案并不比 PHP 手册更有帮助。
    猜你喜欢
    • 2020-07-08
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多