Проблема с AES_DECRYPT при получении из базы данных MySQL

Итак, у меня есть эта страница, которая должна позволить пользователю войти в систему со своим паролем, который зашифрован в базе данных с помощью 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

Решение

В вашем запросе есть синтаксическая ошибка, но об этом позже. Вы бы нашли его, если бы проверили свои звонки 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 обеспечивает password_hash() для этой цели в PHP 5.5+, и есть шайма, которую вы можете использовать для более ранних версий.

Если ваш профессор учит вас использовать AES_ENCRYPT() для обеспечения безопасности паролей вы действительно должны взять его на себя задачу.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector