2015-01-02 107 views
2

我测试了不同的密码加密方式,除了我对使用的脚本的password_verify函数感到困惑之外,我已经使用了大多数方法,以及如何在脚本中实现它(请参见下文) 。该脚本涉及注册和登录等。该脚本成功使用下面这行代码散列密码。password_verify - 密码散列

$passwordhash = password_hash($p, PASSWORD_DEFAULT); 

(从注册)

,但是当我尝试使用我的登录脚本密码,以核实这是行不通的。所以我的问题是我如何在下面的代码中使用password_verify函数。

<?php 
//this is executed on another page 
if(isset($_POST["e"])){ 
    // Connect to db 
    include_once("databaseconnection.php"); 
    //gather posted and sanitize 
    $e = mysqli_real_escape_string($db_conx, $_POST['e']); 
    $p = ($_POST['p']); 
    //user ip 
    $ip = preg_replace('#[^0-9.]#', '', getenv('REMOTE_ADDR')); 
    // FORM DATA ERROR HANDLING 
    if($e == "" || $p == ""){ 
     echo "login_failed"; 
     exit(); 
    } else { 
    //data error handling end 
     $sql = "SELECT id, username, password FROM users WHERE email='$e' AND activated='1' LIMIT 1"; 
     $query = mysqli_query($db_conx, $sql); 
     $row = mysqli_fetch_row($query); 
     $db_id = $row[0]; 
     $db_username = $row[1]; 
     $db_pass_str = $row[2]; 
     if($p != $db_pass_str){ 
      echo "login_failed"; 
      exit(); 
     } else { 
      //create session cookies 
      $_SESSION['userid'] = $db_id; 
      $_SESSION['username'] = $db_username; 
      $_SESSION['password'] = $db_pass_str; 
      setcookie("id", $db_id, strtotime('+30 days'), "/", "", "", TRUE); 
      setcookie("user", $db_username, strtotime('+30 days'), "/", "", "", TRUE); 
      setcookie("pass", $db_pass_str, strtotime('+30 days'), "/", "", "", TRUE); 
      //update certain fields ip, last login time 
      $sql = "UPDATE users SET ip='$ip', lastlogin=now() WHERE username='$db_username' LIMIT 1"; 
      $query = mysqli_query($db_conx, $sql); 
      echo $db_username; 
      exit(); 
     } 
    } 
    exit(); 
} 
?> 

(我试过了,失败了,与此代码使用password_verify funcion)

$p = password_verify($_POST['p'], $passwordhash); 

很抱歉,如果这是很难理解,但它会很感激,如果我有人可以帮助: - )

+0

password_verify函数将返回一个布尔值。如果条件检查语句为真,您需要使用 –

+0

您的代码容易受到[Second Order SQLi](https://haiderm.com/second-order-sql-injection-explained-example/)的影响。始终使用参数而不是'mysqli_real_escape_string',因为从长远来看,您会发现它更容易。 – SilverlightFox

回答

3

假设您存储在数据库中的密码已被散列化,您的问题在于您无法验证密码,因为您正在比较纯文本密码和散列代码。

我相信改变

if($p != $db_pass_str){ 
     echo "login_failed"; 
     exit(); 
    } 

if(!password_verify($p, $db_pass_str)) { 
     echo "login_failed"; 
     exit(); 
} 

应该解决您的问题,看看在password_hashpassword_verify

+0

我的数据库中的密码已成功散列。有了上面的代码,我应该改变行$ p =($ _POST ['p']);还是应该让它保持不变?谢谢你的帮助。 –

+0

保持不变,$ p = $ _POST ['p']只是将通过浏览器发送的密码分配给一个变量。所以你希望它相同,然后使用密码验证内部检查,以查看明文密码的散列是否与提供的散列匹配。 –

0

你有这样的:

$ p =($ _POST ['p']);

但后来什么也不做这个之前,改变$ P:(!$ P = $ db_pass_str)

如果{什么是典型的

思考,这是非典型的哈希做客户端和非典型的数据库以纯文本存储密码,所以我最好的猜测是表单传递一个非哈希密码和数据库存储哈希密码。除非您要在登录表单中输入密码哈希值,否则导致第二条引用线失败。

如果这不是问题,那么可能会发布一些额外的上下文。

+0

我明白你的意思了。使用md5和sha1稍微容易一些(但不太安全)。我通常只需添加md5就可以了,例如$ p = md5($ _ POST ['p']);但是使用password_verify很难以这种方式来翻译它,因为我不能只将password_verify作为md5的前面。 $ p = password_verify($ _ POST ['p']);将无法工作。 –