【问题标题】:Why my password hash is returning false when i provide the correct password?当我提供正确的密码时,为什么我的密码哈希返回错误?
【发布时间】:2019-11-15 21:26:34
【问题描述】:

当我对密码进行哈希处理时,我使用了 password_hash($password, PASSWORD_ARGON2I)。

现在我想根据存储在我的 sql 服务器中的哈希密码来验证我的登录密码。但是,即使我提供了正确的密码,password_verify 仍然返回 false。有人可以帮忙吗?

我曾尝试在 google 和 stackoverflow 上搜索解决方案,但无济于事

if(isset($_POST['login'])) {

    $username = strip_tags(trim($_POST["username"]));
    $password = $_POST["password"];

    $query = "SELECT * FROM USERNAME WHERE user_id= '".$username."' ";
    $params = array();
    $stmt = sqlsrv_query($conn, $query);

    $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);

    $hash_password = $row['password'];

    $new = password_verify($password, $hash_password);


    if(var_dump(password_verify($password, $hash_password))){

        $msg = "Login Success"; 

    }else{

        $msg = "Login failure";

    }

    echo $msg;
}

输出返回“登录失败”

【问题讨论】:

  • 去掉var_dump(),应该是if(password_verify($password, $hash_password)){
  • @RiggsFolly 不起作用。我试过了
  • 也停止摆弄$_POST["username"] 并更改 SQL 以使用准备好的参数化和绑定查询

标签: php sql hash passwords


【解决方案1】:

var_dump() 总是返回“void”。 password_verify() 返回“布尔”。所以你必须直接检查password_verify()。

!警告!

您的代码对 SQL 注入开放!我不建议使用您的代码。 但是,由于您特别要求一件事,这可能会起作用:

if(password_verify($password, $hash_password)){
    $msg = "Login Success"; 
} else {
    $msg = "Login failure";
}

【讨论】:

  • 我发现了问题所在。我用于密码列的数据类型是 nvarchar(300)。当我将其更改为 nvarchar(MAX) 时。终于成功了!!!
  • 感谢您提出这个问题。您能否启发我如何改进我的代码以防止 SQL 注入?仅供参考,我的应用程序连接到 SQL Server,而不是 mysql 数据库。
  • SQL注入不是mysql独有的东西。每个使用某种 sql 方言的数据库都会受到它的影响。您应该使用准备好的语句来防止大多数可能的攻击。
【解决方案2】:
  1. 弄乱输入是危险的,您可能会通过使用 strip_tags 影响userid 的内容,如果您使用准备好的查询,则无论如何都是不必要的。

  2. 在这一行中使用var_dump() if(var_dump(password_verify($password, $hash_password))){ 将始终导致错误,因为var_dump() 返回NULL。

  3. sqlsrv_ 调用添加一些错误检查也是一个好主意。

所以建议修改代码

if(isset($_POST['login'])) {

    //$username = strip_tags(trim($_POST["username"]));
    //$password = $_POST["password"];

    $query = "SELECT * FROM USERNAME WHERE user_id= ?";
    $params = array($_POST["username"]);
    $stmt = sqlsrv_prepare($conn, $query, $params);
    if( !$stmt ) {
        print_r( sqlsrv_errors(), true);
        exit;
    }

    if( sqlsrv_execute( $stmt ) === false ) {
        print_r( sqlsrv_errors(), true);
        exit;
    }

    $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);

    //$hash_password = $row['password'];
    //$new = password_verify($password, $hash_password);
    //if(password_verify($password, $hash_password)){

    if(password_verify($_POST["username"], $row['password']))){
        $msg = "Login Success"; 
    }else{
        $msg = "Login failure";
    }
    echo $msg;
}

当然要检查的另一件事是密码的散列是否正常工作,如果失败,您将永远无法进行验证。

【讨论】:

    【解决方案3】:

    在解决 RiggsFolly SQL 注入问题时,我重做我的代码,如下所示。希望这是正确的方法。

    if(isset($_POST['login'])) {
    
        $username = $_POST["username"];
        $password = $_POST["password"];
    
        $query = "SELECT * FROM USERNAME WHERE user_id= ? ";
        $params = array($username);
        $stmt = sqlsrv_prepare($conn, $query, $params);
    
        if(sqlsrv_execute($stmt)){
    
            $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
    
            $hash_password = $row['password'];
    
            $new = password_verify($password, $hash_password);
    
            if(password_verify($password, $hash_password)){
    
                $msg = "Login Success"; 
    
            }else{
    
                $msg = "Login failure";
    
            }
    
        }
    
    }
    

    【讨论】:

    • 大概是我在回答中的建议
    猜你喜欢
    • 2011-09-10
    • 2016-01-21
    • 2017-08-16
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多