好的,我有这个页面,应该允许用户使用他们的密码登录,密码在数据库中用AES加密。我想从数据库中取出加密的密码,对其进行解密,并将其与用户输入的密码进行比较。这是我的代码:
<?php
session_start();
$validUser = false;
// see if they want to logout from a current session
$tOption = $_GET['cmd'];
if($tOption=="logout") {
unset($_SESSION['SAFEUSER']);
}
?>
<html>
<body>
<?php
// are they attempting to log into the menu?
// alternative syntax that uses the submit button's value
// if( $_POST['Fsubmit'] == "lookupnow" ) {
if( ($_POST['Femail'] > "") or ($_POST['Fpassword'] > "") ) {
// look 'em up in the database to validate credentials
// establish values for DB credentials
$hostname = 'localhost';
$dbname = '';
$username = '';
$userpass = '';
$passkey = "sgjbasjgbaslhflshfoashf";
// get connected to the DB
try {
$DBH = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $userpass);
}
catch(PDOException $e) {
echo $e->getMessage();
}
$tEmail = $_POST['Femail'];
$tPassword = $_POST['Fpassword'];
/*$secureSQL = 'SELECT FirstName, LastName, Phone from Members WHERE Email="'
. $tEmail . '" AND Password="' . $tPassword . '"';*/
$secureSQL = 'SELECT FirstName, LastName, Phone from Members WHERE Email="'
. $tEmail . '" AND AES_DECRYPT(Password, $passkey) ="' . $tPassword . '"';
//echo $secureSQL . "<br>";
// estalish SQL query
$STH = $DBH->query($secureSQL);
# setting the fetch mode -- this comes into effect when the fetch() function is called
$STH->setFetchMode(PDO::FETCH_ASSOC);
while($row = $STH->fetch()) {
$validUser = true;
$_SESSION['SAFEUSER'] = true;
}
if($validUser==false) {
echo "<font color='red'>Those credentials were not authenticated.</font><br/><br/>";
}
}
// are they logged in?
if(!$_SESSION['SAFEUSER']) {
// if not, make them login
?>
Please enter your credentials:<br />
<form method="post" action="mysecuremenu.php">
Your email address: <input type="text" name="Femail"><br>
Your password: <input type="password" name="Fpassword"></br>
<input type="submit" name="Fsubmit" value="lookupnow">
</form>
<?php
} else {
// otherwise, show them the menu
?>
<h2>Please select one of the following:</h2>
<ul>
<li><a href="MySecureFirstDBForm.php">Enter a new employee</a></li>
<li><a href="mySecuredbviewall_withdatatable.php">View all employees</a></li>
<li><a href="mysecuremenu.php?cmd=logout">Logout</a></li>
</ul>
<?php
} // end if(safeuser)
?>
</body>
</html>
我得到这个错误:
Fatal error: Call to a member function setFetchMode() on a non-object on line 58
我觉得这与我的SELECT语句有关,因为我在上面评论的那个语句适用于使用非加密密码登录。我将感谢所有的帮助。谢谢
您的查询中有语法错误,稍后会详细介绍。如果您检查了对PDO
的呼叫是否有错误,您就会找到它。PDO
不会显式标记错误,除非您要求它这样做,所以您需要检查对$DBH->query(...)
的调用的返回值
$STH = $DBH->query($secureSQL);
if ($STH === false) {
$errorInfo = $DBH->errorInfo();
echo $errorInfo[0].':'.$errorInfo[1].' ('.$errorInfo[2].')';
exit;
}
(您可以将PDO设置为在遇到错误时抛出异常,并使用try...catch
块来处理它。这是读者的练习)
现在-语法错误。你正在构建这样的查询:
$secureSQL =
'SELECT FirstName, LastName, Phone from Members WHERE Email="'
. $tEmail . '" AND AES_DECRYPT(Password, $passkey) ="' . $tPassword . '"';
您已经尝试对$passkey
变量进行插值,但字符串的这一部分用单引号括起来,因此插值不起作用。您已经连接了其余的参数,所以不清楚为什么您在这里做了一些不同的事情。
您还省略了在$passkey
周围加单引号,因此即使插值有效,查询也会失败。简单地交换你对单引号和双引号的使用会让这变得更容易。
你需要这个:
$secureSQL =
"SELECT FirstName, LastName, Phone from Members WHERE Email='"
. $tEmail . "' AND AES_DECRYPT(Password, '$passkey') ='" . $tPassword . "'";
还有更多。
您已将用户输入直接添加到查询字符串中,而无需任何形式的转义。这让您对SQL注入持开放态度。再加上加密密码,你就可以公开邀请黑客攻击你的数据库。至少应该使用PDO::quote()
来转义变量,但更好的方法是使用准备好的语句并完全避免注入风险。(读者的另一个练习)。
最后(这已经在评论中介绍过了)不要加密密码-对它们进行哈希PHP在PHP 5.5+中为此提供了password_hash()
,并且有一个可以用于早期版本的填充程序。
如果你的教授教你使用AES_ENCRYPT()
来保护密码,你真的应该让他负责