另一个password_verify()问题可能与数据库有关

时间:2017-04-29 11:29:14

标签: php mysql passwords

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

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查询中动态创建的。它创建了&amp;被手动复制到数据库中。 请帮忙

2 个答案:

答案 0 :(得分:0)

echo password_verify("",'$2y$10$HwC2tF1hELiqJ2QEL8Oeju1L3Ore26GSnxh6CiibPbiNwPIpVUIfi')."\n";

返回1.

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

鉴于您拥有的代码很乱,难怪它在某处错过了。

答案 1 :(得分:0)

一些观察结果:

  1. 有利于您使用password_hash而不是尝试重新发明密码安全性。

  2. 您已向我们展示register()doLogin()的功能,但您尚未向我们展示如何调用这些功能。他们似乎被错误的参数调用了。调试时,回复或转储明文密码没有坏处,以确保您拥有自己认为的值。

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

  4. password_verify()函数返回true或false。

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

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

        $one = $resp["salt"];
        $two = $resp['salt'];
    
    1. 我希望您表格中的哈希密码列名为hashed_password,而不是salt。由于这一点,我在阅读代码时经历了几分钟的混乱,当你两年后再回到这段代码时,你也会这样。如果其他人维护你的代码,她会诅咒你的名字这种事情。这种代码是长寿的:仔细构建它。

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