从MySQL数据库检索时出现AES_DECRYPT问题

时间:2015-02-23 22:16:21

标签: php mysql aes

好的,所以我有这个页面应该允许用户使用他们的密码登录,密码是用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语句有关,因为我在上面评论过它可以正常使用非加密密码登录。我将不胜感激任何帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

您的查询中存在语法错误,但稍后会有更多错误。如果您检查了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()来保护密码,你真的应该让他去完成任务。