【问题标题】:Another password_verify() issue possibly database related另一个 password_verify() 问题可能与数据库相关
【发布时间】:2017-04-29 11:29:14
【问题描述】:

在发布之前,我已经查看了一堆其他问题。在这一点上,我已经厌倦了用头撞墙。 从注册页面移动到与数据库有某种关联的登录页面时似乎存在问题。

class USER
{   

private $conn;

public function __construct()
{
    $database = new Database();
    $db = $database->dbConnection();
    $this->conn = $db;
}



public function register($fname,$l_init,$umail,$upass)
{
    try
    {
        $new_password = password_hash($upass, PASSWORD_DEFAULT);

        $stmt = $this->conn->prepare("INSERT INTO users(first_name,last_initial,email,salt) 
                                                   VALUES(:fname, :l_init, :umail, :upass)");

        $stmt->bindparam(":fname", $fname);
        $stmt->bindparam(":l_init", $l_init);
        $stmt->bindparam(":umail", $umail);
        $stmt->bindparam(':upass', $new_password);                                        



        if(password_verify($upass, $new_password))
        {
            $stmt->execute();
            echo "password verify works"; //$stmt->rowCount();
        }
        else
        {
            echo "password verify is corrupt";
            sleep(5);
            die;
        }
        //$resp = $stmt->fetch(PDO::FETCH_ASSOC);   

        /*if($stmt->rowCount() == 1)
        {
            $success = "New User created! Redirecting....";
        }
        else
        {
            $success = false;
        }

        return $success;    */
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }               
}


public function doLogin($umail,$upass)
{
    try
    {
        $stmt = $this->conn->prepare("SELECT * FROM users WHERE email=:umail");
        //bind params here
        $stmt->bindparam(":umail", $umail);


        $stmt->execute(); 

        echo $stmt->rowCount(); //echo if there is a returned result row

        $resp = $stmt->fetch(PDO::FETCH_ASSOC);


// checking for any variance between single/double quotes
        $one = $resp["salt"];
        $two = $resp['salt'];

        echo "first check".$one;
        echo "<br> second check" . $two . "<br>";

        //original check for existance of a match
        if($stmt->rowCount() == 1)
        {   session_start();

            echo "third check" . $upass  . '<br>';              
            echo "4th check" . password_verify($upass, $resp['salt']) . '<br>';


        echo "hash gen" . password_hash($upass, PASSWORD_DEFAULT) . '<br>';
        if($resp['salt'] == password_hash($upass, PASSWORD_DEFAULT))
            {echo "true somehow";}
        sleep(20);


            if(password_verify($upass, $resp['salt']))
            {
                session_start();
                $_SESSION['user_session'] = $resp['first_name'];
                return true;
            }
            else
            {
                return false;
            } 
        }
        else
        {
        $e_response = "Were sorry but that email is not Registered <br> Please check your spelling and try again";
        return $e_response;
        }
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
}

1) 数据库存储为 varchar 255。 在尝试将新用户注册到数据库中时,会导致正确的密码验证测试。 但是,我所有强制 password_verify 使用 doLogin 函数的尝试都失败了。

我已经加入了一些混乱的回声,只是为了看看实际输出的是什么。

我看到的是以下内容:

first check$ 2y$10$HwC2tF1hELiqJ2QEL8Oeju1L3Ore26GSnxh6CiibPbiNwPIpVUIfi
second check $2y$10$HwC2tF1hELiqJ2QEL8Oeju1L3Ore26GSnxh6CiibPbiNwPIpVUIfi
third check  testpass    
4th check    (blank- assuming this means false? or something else?)
hash gen     $2y$10$K5j3GlqjQ7OVew9yj1FbRuF1FFin9egPVq/Uzv8D0UzsU/LKH4FDa

我整晚都在想我可能做错了什么。 我有一个可以识别密码的原始数据库用户,但是该哈希不是在 SQL 查询中动态创建的。它是创建并手动复制到数据库中的。 请帮忙

【问题讨论】:

  • var_dump() 你的第四次检查,确保它是否失败。
  • bool(false) 第四次检查

标签: php mysql passwords


【解决方案1】:
echo password_verify("",'$2y$10$HwC2tF1hELiqJ2QEL8Oeju1L3Ore26GSnxh6CiibPbiNwPIpVUIfi')."\n";

返回 1。

表示在 register() 中传递的 $uppass 为空。

鉴于你的代码很乱,难怪它在某个地方被遗漏了。

【讨论】:

  • 呜咽!谢谢你,先生。原来我的表单中有一个简单的错字,没有传递变量,而是一个空字符串。 (在此处插入 facepalm)我现在清理代码
【解决方案2】:

一些观察:

  1. 使用 password_hash 对您有好处,而不是尝试重新发明密码安全性。

  2. 您已经向我们展示了 register()doLogin() 的函数,但您没有向我们展示如何调用这些函数。似乎使用不正确的参数调用它们。在调试时,回显或转储明文密码以确保您拥有您认为拥有的值,这并没有什么坏处。

  3. 每次使用相同的明文密码调用 password_hash() 都会生成不同的散列值:password_hash() 生成并使用加密随机盐(以减缓试图使用查找表破解密码的网络犯罪分子系统)。

  4. password_verify() 函数返回真或假。

  5. 散列密码包含$ 字符。因此,如果在 php 中将它们写为常量,则必须将它们括在单个 ' 引号中,因为 php 会尝试在带有双 " 引号的字符串中进行变量替换。

但是:这不是你的问题。您的程序中没有任何包含散列密码的字符串常量。在这里,您尝试在数组元素的名称中使用单引号或双引号。这不是那个选择产生影响的背景。

    $one = $resp["salt"];
    $two = $resp['salt'];
  1. 我希望表中的哈希密码列被命名为 hashed_password 而不是 salt。由于这个原因,我在阅读您的代码时遇到了几分钟的困惑,两年后当您回到这段代码时,您也会感到困惑。如果其他人维护您的代码,她会因为这种事情而诅咒您的名字。这种代码寿命很长:仔细构建它。

  2. 聪明的程序员避免使用SELECT *。最好给出您想要的列的名称。在系统的早期阶段尤其如此,在您将新列添加到关键表之前。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    • 2012-12-08
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    相关资源
    最近更新 更多