【问题标题】:PHP SHA256 and Salt won't workPHP SHA256 和 Salt 不起作用
【发布时间】:2014-03-04 01:45:30
【问题描述】:

我正在尝试创建带有 $salt 变量的 sha256 散列密码。但由于某种原因,它只是行不通。现在已经为此工作了 3 个小时,我正要扯掉我的头。这是我的代码:

我会再试一次,对不起;o)

好的,我的脚本运行良好,直到我尝试将 sha256 添加到密码中。我有一个用于创建用户的文件:

$salt = "lollol";  
$password = hash('sha256', $salt.$_POST['password']);  
$sql = ("INSERT INTO members (username, password, name, last_name,company)VALUES('$username', '$password', '$name', '$last_name', '$company')")or die(mysql_error());

if(mysql_query($sql))
    echo "Your accuont has been created.";

它似乎已正确添加到数据库中。我可以看到它被一些字母和数字散列。

但是当我尝试登录时,它就不会了。

我的 login.php 代码是:

$sql= "SELECT * FROM members WHERE username='$username' and password='$password'";  
$result=mysql_query($sql);    
$row=mysql_fetch_array($result);  
$username = mysql_real_escape_string($_POST['username']);  
$password = $_POST['password'];  
$salt = "lollol";  
$auth_user = hash('sha256', $salt.$password);  
if($password == $salt.$auth_user){  
    echo "Logged in";  
} else {  
    echo "Not logged in";  
}  

我明白了,我想登录时必须加密密码,但我不确定。我希望你们中的一些人可以帮助我。

【问题讨论】:

  • 是的,代码太多了。请尝试将您的代码 sn-p 减少到显示问题所需的最低。目前,您混合了验证、正则表达式、SQL、会话变量和 HTML 生成。
  • 你最好只做一个最小的例子(非常你至少可以做的是删除 cmets,但最后:首先解释应该发生什么,然后显示给我们一小段代码,然后解释发生了什么以及为什么这会让您感到惊讶。这样帮助会更容易!
  • @Oli Charlesworth 我现在已经解决了我的问题。
  • @KingCrunch 我现在已经编辑了我的问题。

标签: php sha256


【解决方案1】:

在尝试登录时,您再次将哈希与盐连接起来

$auth_user = hash('sha256', $salt.$password);
if($password == $salt.$auth_user){ // <-- $salt once more
  echo "Logged in";
} else {
  echo "Not logged in";
}

它应该可以工作,如果你只是删除它

$auth_user = hash('sha256', $salt.$password);
if($password == $auth_user){
  echo "Logged in";
} else {
  echo "Not logged in";
}

更新:更进一步

这里

$sql= "SELECT * FROM members WHERE username='$username' and password='$password'";

您尝试检索用户名与$username 匹配且密码与$password 匹配的行。在数据库中,密码已经被散列($password 似乎根本没有定义),因此这个查询将永远返回任何行。

$password = hash('sha256', $salt.$_POST['password']);
$username = mysql_real_escape_string($_POST['username']);
$sql= "SELECT * FROM members WHERE username='$username' and password='$password'";
$result=mysql_query($sql);

$result 现在应该包含与给定凭据匹配的 only 用户。现在很容易

if (mysql_num_rows($result) === 1) {
  echo "Logged in";
} else {
  echo "Not logged in";
}

【讨论】:

  • @KingCrunch 它似乎不起作用。仍然不会回显“已登录”。
  • 请注意,这仍然没有意义。现在我们正在检查 $password == hash('sha256', $salt.$password)! ($password==的两边...)
  • @Ole Charlesworth 我可以看到。 id 应该是什么样子?
  • @Oli:你是对的。它必须是$row 之外的密码。我会更新我的答案。更新:请意识到,查询也是毫无意义的......
  • @KingCrunch 然后现在。那你为什么不能告诉我我的sql应该是怎样的呢?
【解决方案2】:

您正在存储一个加密的密码,但您的选择查询正在寻找未加密的密码。

只需获取匹配的用户名(没有密码条件) - 用户名是唯一的,对吗?:

$sql= "SELECT * FROM members WHERE username='$username'";  
$result=mysql_query($sql);    
$row=mysql_fetch_array($result);  
$username = mysql_real_escape_string($_POST['username']);  
$password = $_POST['password'];  
$salt = "lollol";  
$auth_user = hash('sha256', $salt.$password);  
if($row["password"] == $auth_user){  
    echo "Logged in";  
} else {  
    echo "Not logged in";  
}  

【讨论】:

    【解决方案3】:
    $password = $_POST['password'];
    
    // This should be the users actual salt after you've found the user
    // in the database by username or email, or other means
    $salt = $users_stored_salt;
    
    // This should be the exact method you use to salt passwords on creation
    // Consider creating a functon for it, you must use the same salt
    // on creation and on validation
    $hashed_password = hash('sha256', $salt.$password.$salt);
    
    // This is the user's hashed password, as stored in the database
    $stored_password = $users_stored_password;
    
    // We compare the two strings, as they should be the same if given the
    // same input and hashed the same way
    if ($stored_password === $hashed_password){
        echo "Logged in";
    } else {
        echo "Not logged in";
    }
    

    错过了您的编辑,但希望这会有所帮助。

    编辑:我看到您没有存储唯一的哈希值。

    如果您通过密码查找用户,则需要在查询中以与存储密码相同的方式对密码进行哈希处理:

    $salt = $your_salt;
    
    $hashed_password = hash('sha256', $salt.$_POST['password']);
    
    $sql= "SELECT * FROM members WHERE username='$username' and password='$hashed_password'";  
    

    否则,您可以通过唯一的用户名(而不是密码)查找,然后将散列输入与存储的密码值进行比较。

    我现在很困惑。我的 login_ac.php 应该是什么样子,如果我应该使用我在顶部给你的代码来实现它?

    只需将查询更改为通过散列密码(您存储密码的方式)查找即可。

    $sql= "SELECT * FROM members WHERE username='$username' and password='".hash('sha256', $salt.$_POST['password'])."'";  
    

    您可以删除其他验证和散列 - 如果您找到用户,那么您知道输入是有效的。

    请注意,这仅在您知道散列输入的方式与您在创建时散列密码的方式完全相同时才有效。

    【讨论】:

    • @Wesley Murch 我现在很困惑。我的 login_ac.php 应该是什么样子,如果我应该使用我在顶部给你的代码来实现它?
    • @Wesley Murch 嗯,我在想 Ole 写的内容: $password 位于 == 的两侧,可以吗? o.O 我对这个 sha256 很陌生
    • @Wesley Murch - 我在创建帐户时以这种方式散列: $salt = "lollol"; $password = hash('sha256', $salt.$_POST['password']);
    • @Kolind: 看看Pavling's answer 很抱歉让你对第一部分感到困惑,我真的不认为“lolol”是你实际上对密码进行加盐的方式,我认为这是一个伪代表用户唯一哈希的值。
    • @Wesley Murch 我已经做到了。现在我看起来和他的回答完全一样。但它仍然不起作用。我的密码字段应该是多少个 VARCHAR()?
    【解决方案4】:

    值得检查数据库中的字段长度是否足够大以存储整个散列密码而不截断它。如果存储的密码没有结尾,登录时您将永远不会得到密码匹配。

    【讨论】:

      猜你喜欢
      • 2015-01-27
      • 1970-01-01
      • 2017-05-03
      • 1970-01-01
      • 2016-06-11
      • 2011-05-15
      • 2015-10-19
      • 2012-12-16
      • 2012-06-28
      相关资源
      最近更新 更多