【问题标题】:PHP password_verify Returning False When Retrieving Hashed PW from DatabasePHP password_verify 在从数据库中检索散列密码时返回 False
【发布时间】:2019-03-14 11:45:38
【问题描述】:

我已经搜索了 SO 内部和外部的线程,但没有解决问题。

背景:使用 PHP、Wordpress 和 ACF(高级自定义字段)创建一个小型登录系统。保存包含密码的帖子后,密码会被散列,并在数据库中替换值。到目前为止一切顺利(据我所知)。当用户访问登录页面,提交密码尝试时,验证 php 文件调用 Wordpress API,检索存储的散列密码,然后运行 ​​password_verify。每次运行时,它都会返回 false。下面的代码...

    $pw_submit = $_POST['pw-submit'];

    //Call WP API
    $urlPrefix = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ?
    'https' : 'http';
    $siteURL = $urlPrefix . "://" . $_SERVER['SERVER_NAME'];
    function callAPI($method, $url, $data){
        $curl = curl_init();
        $url = sprintf("%s?%s", $url, http_build_query($data));

        // OPTIONS:
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: 
            application/json'));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        // EXECUTE:
        $result = curl_exec($curl);
        if(!$result){die("Connection Failure");}
            curl_close($curl);
            return $result;
    }

    $get_data = callAPI('GET', $siteURL . '/wp-json/acf/v3/pages/25', false);
    $response = json_decode($get_data, true);
    $db_password = $response[acf][portal_password];        

    if( password_verify( $pw_submit, $db_password) ){
        echo "Well that worked";
    }
    else{
        echo "No it didn't";
    }

即使我复制/粘贴散列密码并尝试验证,它仍然返回 false...

    $hash = '$2y$10$2/PuBIYuhEJ69fSc2/ae.OOVr4nMrpKu.9ahRm90TuSBu0EJulWki';
    $verify = password_verify('foobar', $hash);
    var_dump($verify);

...它返回 bool(false)。

password_verify 返回 true 的唯一方法是我创建散列密码并立即验证它。所以在验证脚本中...

    $pw_hash = password_hash('foobar', PASSWORD_DEFAULT);
    $verify = password_verify('foobar', $pw_hash);
    var_dump($verify); // Returns TRUE

我检查了数据库并确保表格单元格保存了整个哈希(当我 var_dump 提取的值时,我得到一个 60 个字符的字符串)。我通过使用 trim() 确保之前/之后没有空格。我尝试用单引号替换包含散列字符串的包含双引号。我不知道缺少什么/出了什么问题。非常感谢任何帮助/指导。谢谢!

更新 所以这里的错误是我在修复以前的问题时忘记更新变量。对于那些可能偶然发现这一点的人来说,最初的问题是 Wordpress 运行我的哈希脚本两次,导致第一个哈希密码的哈希值。因此,请始终检查 wordpress 实际在做什么。此外,我遇到的一件事是使用 ACF get_field() 来获取未散列的密码,但是因为我使用的是 wp_insert_post_data() 过滤器,所以我实际上是在获取旧/当前值,而不是获取新/输入密码。通过使用“acf/save_post”过滤器解决了这个问题。谢谢大家的帮助!

【问题讨论】:

  • 注意 $db_password = $response[acf][portal_password]; 应该是 $db_password = $response['acf']['portal_password'];
  • $2y$10$2/PuBIYuhEJ69fSc2/ae.OOVr4nMrpKu.9ahRm90TuSBu0EJulWki 是空字符串的有效哈希。如果那是您的真实数据,请找出它的来源并修复创建它的代码。
  • GrumpyCrouton 谢谢,我已经确认无引号可以正常工作。 @iainn我已经尝试过各种字符串,但如果我当时在那里创建哈希,它似乎只会验证真实。从数据库中提取时,我感觉好像发生了一些事情,但无法弄清楚是什么,因为我尝试了多种方式来清理字符串。
  • 我的意思是,您在此处发布的验证码看起来不错,但存储在您的数据库中的哈希值并不是您认为的那样。不管是什么创建的,哈希都没有在正确的字符串上运行——它是一个有效的 bcrypt 哈希,但它是一个空字符串。 var_dump(password_verify('', '$2y$10$2/PuBIYuhEJ69fSc2/ae.OOVr4nMrpKu.9ahRm90TuSBu0EJulWki')); bool(true)
  • @iainn 对不起,我误解了你的意思。你是对的!我正在散列一个空字符串。我现在意识到,在最后一天,由于另一个问题,我重新编写了我的哈希脚本,并且错过了变量替换。谢谢!如何将您的评论标记为正确?想确保你得到你的互联网积分:)

标签: php wordpress passwords advanced-custom-fields password-encryption


【解决方案1】:

$db_password = $response[acf][portal_password]; 没有正确格式化的索引。请改用$db_password = $response['acf']['portal_password'];

由于此错误,password_verify($pw_submit, $db_password) 正在使用不包含任何信息的变量 $db_password 验证用户输入的密码。

【讨论】:

  • 不带引号的数组索引在 PHP 中可以正常工作,尽管它们会在执行时发出通知/警告。它不会导致变量有任何不同。
  • 感谢 Brxxn,已经确认 $db_password 正在接收数据(使用 var_dump),但为了确保我尝试了您的建议,结果相同,没有骰子。 :(
猜你喜欢
  • 2013-04-23
  • 2015-12-01
  • 1970-01-01
  • 2012-07-22
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多