【问题标题】:PHP x==x but if statement says x!=xPHP x==x 但如果语句说 x!=x
【发布时间】:2015-05-11 11:00:15
【问题描述】:

我有一个checklogin.php:

<?php

$host="localhost"; // Host name 
$username="user"; // Mysql username 
$password="pass"; // Mysql password 
$db_name="database1"; // Database name 
$tbl_name="users"; // Table name 
$lastLogDate=date("l, m/d/y, h:i:sa");
// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
mysql_select_db("$db_name")or die("cannot select DB");

// username and password sent from form 
$myusername=$_POST['myusername']; 
$mypassword=$_POST['mypassword']; 

// To protect MySQL injection (more detail about MySQL injection)
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);

$sql="SELECT password FROM $tbl_name WHERE username='$myusername'";
$result=mysql_query($sql);
$realpassword=mysql_result($result, 0);

define("ENCRYPTION_KEY", "!@#$%^&*");
function decrypt($encrypted_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, $encryption_key, $encrypted_string, MCRYPT_MODE_ECB, $iv);
    return $decrypted_string;
}
$realpassword=decrypt($realpassword, ENCRYPTION_KEY);

if ($mypassword == $realpassword) {
session_register("myusername");
session_register("mypassword"); 
session_register("userid");
session_register("finalemail");
$sqldate="UPDATE userdata SET lastLog = '$lastLogDate' WHERE username = '$myusername'";
$resultdate=mysql_query($sqldate);
header("location:/home");
}
else {
echo "Wrong Username or Password<br>";

}
?>

当有人使用login.php登录时,输入的密码与解密后数据库中的密码相同,仍然提示“用户名或密码错误”。我添加了一个回显以查看解密是否有效,但它返回正确。我创建了一个新帐户并尝试使用该帐户登录,并且成功了。这仅在我添加加密之前不适用于帐户,我只是自己加密了密码。也许这就是问题所在?

【问题讨论】:

  • 不要将密码以可逆的形式存储在数据库中。这就是hashing 的用途。
  • 我不认为这是问题所在。之后我创建了一个新帐户,并且效果很好。可能是因为我手动加密了之前创建的账户密码?
  • 最好的选择是从后端查询您的数据,然后将结果与您的前端进行比较。我可以假设以前的数据/密码是散列的,而你比较的新密码不是。
  • 这不是导致您的问题的原因,而是一般的安全问题。密码应该是散列的,而不是加密的。哈希表示不可逆(一种方式),加密是可逆的(两种方式)。您使用唯一的用户盐对给定密码进行哈希处理,并且该哈希应该等于存储在数据库中的内容。
  • 您正在预处理用户密码,包括使用mysql_real_escape_string() 对其进行转义。然后,您将密码的转义版本与现阶段未转义的解密版本进行比较,因此它们不匹配也就不足为奇了。如果 PHP 说变量不匹配,那么可以肯定的是它们不匹配。在比较它们之前尝试在这两个变量上使用var_dump(),看看你实际有什么值。

标签: php if-statement encryption


【解决方案1】:

你的问题是双重的。

首先,mcrypt 在编码之前用尾随空字节填充您的数据(如果您自己不应用填充,例如 PKCS7);解码后你需要去掉那些空字节:

$realpassword = rtrim($realpassword, "\0");

其次,你不应该对密码使用加密;相反,使用password hashing API;示例见this answer

【讨论】:

  • @k97513 不客气;请查看有关此主题的 my earlier answer 以获取如何使用密码散列的示例。
  • @k97513 另外,正如 islq 所提到的,您不应该转义 $mypassword,因为您应该始终与给定值进行比较。
【解决方案2】:

可能是受这些转换影响的旧密码:

$mypassword = stripslashes($mypassword);
$mypassword = mysql_real_escape_string($mypassword);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 2012-12-15
    • 2016-07-07
    • 1970-01-01
    • 2012-08-27
    • 2018-01-21
    • 2011-09-01
    相关资源
    最近更新 更多