在注册和帐户设置中散列密码

Hashing password in register and account settings

当我使用自己的帐户登录测试我的脚本时,出现登录错误。您认为对密码进行两次哈希处理是一种不好的做法吗?

我在我的网站上对用户密码进行了两次哈希处理。一次,当他们注册时,一次,当他们在帐户更新中更新密码时。此外,我正在使用 bcrypt 方法,并且 bcrypting 的成本在两个散列上都是 10,我在本地主机服务器上。

    ///// this is the code in register.php page
    <?php      
    if(isset($_POST['registeruser']))  {
        session_start();
        $FName = $_POST['regfname'];
        $LName = $_POST['reglname'];
        $Email = mysqli_real_escape_string($conn, $_POST['regemail']);
        $origignalpassword = preg_replace('#[^a-z0-9_]#i', '', 
                             $_POST['regpassword']);
        $Passwordw = $_POST['confirmedpassword'];
        $infosql = "SELECT * FROM users WHERE useremail = '".$Email."'";
        $result = mysqli_query($conn,$infosql);
            if(mysqli_num_rows($result)>=1)
                   {
                    echo "Email already taken.";
                   }
                   else if(mysqli_num_rows($result) !=1 && $Passwordw == 
                   $origignalpassword) {
                   $Passwordhash = password_hash($Passwordw, 
                                   PASSWORD_BCRYPT, array('cost' => 10));
                    $sql = $conn->query("INSERT INTO users(firstname, 
                    lastname, useremail, Passwordcell) Values('{$FName}', 
                    '{$LName}','{$Email}','{$Psswordhash}')");
                        header('Location: login.php');
                    } else {
                        echo 'Please check your password:' . '<br>';
                    } 
             }
    ?>


    //// Below code is the code in my update.php page


    <?php session_start();  
        if(isset($_SESSION['user_id'])) { 
            } else {
                header('Location: login.php'); 
            }

        $user = $_SESSION['userid'];
        $myquery = "SELECT * FROM users WHERE `userid`='$user'";
        $result = mysqli_query($conn, $myquery);
        $row = mysqli_fetch_array($result, MYSQLI_BOTH);

        $_SESSION['upd_fnames'] = $row['firstname'];
        $_SESSION['upd_lnames'] = $row['Lastname'];
        $_SESSION['upd_emails'] = $row['useremail'];
        $_SESSION['upd_passwords'] = $row['Passwordcell'];
        $_SESSION['upd_phone'] = $row['phonenum'];
        $_SESSION['upd_bio'] = $row['biography'];   
    ?>
    <?php 
    if (isset($_POST['updateme'])) {
        $updfname = $_POST['upd_fnames'];
        $updlname = $_POST['upd_lnames'];
        $updemail = $_POST['upd_emails'];
        $updphone = $_POST['upd_phone'];
        $upd_pswd = $_POST['upd_passwords'];        
        $biography = $_POST['update_biography'];

        $Pswod = password_hash($upd_pswd, PASSWORD_BCRYPT, 
                 array('cost' => 10));
        $sql_input = $mysqli->query("UPDATE users SET firstname = '{$updfname}', Lastname = '{$updlname}', Phonenum = '{$updphone}', useremail = '{$updemail}', Passwordcell = '{$Pswod}', biography = '{$biography}' WHERE userid=$user");

        header('Location: Account.php');
    }  
    else 
    {

    }
?>

您的问题可能只是一个拼写错误,在您的注册脚本中,而不是 $Passwordhash 您写道:

"INSERT INTO users(..., Passwordcell) Values(...,'{$Psswordhash}')"

不过你的代码还有其他问题,既然你征求了意见,我想分享一下我的想法。

  1. 可能最大的问题是,您的代码容易受到 SQL 注入的攻击。尽快切换到prepared statements,编写代码将变得比像你那样构建查询更容易,而且MYSQLI和PDO都支持它。这 answer 可以给你一个开始。
  2. 不应清理密码。删除行 $origignalpassword = preg_replace('#[^a-z0-9_]#i', '', $_POST['regpassword']),直接将输入传递给哈希函数 password_hash($_POST['regpassword'], PASSWORD_DEFAULT)。 password_hash() 函数适用于任何类型的输入。
  3. 在每次重定向后放置一个退出是一个好习惯,否则脚本将继续执行。 header('Location: login.php', true, 303); exit;
  4. 你真的有理由将用户信息放入会话中吗?而不是 $_SESSION['upd_fnames'] = $row['firstname']; 我会根据需要从数据库中获取信息。通过从数据库中获取它,您可以确保信息已实际设置(不为空)并且是最新的,您可以避免状态并且您可以获得更多的 REST 功能。
  5. 最后但同样重要的是,我建议遵循一些风格规则,比如始终以小写字母开头变量名。您可以避免一些愚蠢的拼写错误,并使您的代码更具可读性。