PHP и MySQL сравнить пароль - PullRequest
       19

PHP и MySQL сравнить пароль

6 голосов
/ 28 января 2009

Как проверить, набрал ли пользователь правильный пароль для входа в систему?

Вот что (из множества комбинаций ...) я делаю:

<?

$login = $_POST['login'];
$password = $_POST['password'];

mysql_connect('localhost', 'root', 'abc123');

mysql_select_db('aun_vox') or die(mysql_error());

$q = mysql_query("SELECT password FROM customer WHERE login='$login'");
$db_pass = mysql_result($q, 0);

if(md5($password) == $db_pass)
{
    echo "You did it.";
}

else echo "Wrong.";

?>

Как я вижу по выходному сигналу, в бите mysql_result что-то не так, но я не могу найти правильный путь.

Может кто-нибудь, пожалуйста, помогите.

Ответы [ 5 ]

17 голосов
/ 28 января 2009

Я вижу, что вы храните хэш пароля в базе данных, но для удобства других читателей, никогда не хранит пароли в виде простого текста в базе данных. Вы не хотите быть , как Monster.com.uk !

Вы должны использовать более сильную функцию хеширования, чем MD5(). В идеале вы должны использовать SHA256. Этот хеш-метод доступен в PHP с использованием функции hash().

Вы также должны применить случайную соль к паролю. Сохраните различные значения соли для учетной записи каждого пользователя. Это помогает отразить атаки по словарю и радужный стол атаки.

Вы должны научиться использовать расширение mysqli вместо старого расширения mysql. Mysqli поддерживает параметризованные запросы, поэтому вы можете уменьшить уязвимость к некоторым атакам с использованием SQL-инъекций.

Вот пример кода. Я не проверял это, но это должно быть довольно близко к работе:

$input_login = $_POST['login'];
$input_password = $_POST['password'];

$stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?");
$stmt->bind_param("s", $input_login);
$stmt->execute();
$stmt->bind_result($password_hash, $salt);

while ($stmt->fetch()) {
  $input_password_hash = hash('sha256', $input_password . $salt);
  if ($input_password_hash == $password_hash) {
    return true;
  }
  // You may want to log failed password attempts here,
  // for security auditing or to lock an account with
  // too many attempts within a short time.
}
$stmt->close();

// No rows matched $input_login, or else password did not match
return false;

Некоторые другие люди предполагают, что запрос должен проверить на login = ? AND password = ?, но я не люблю это делать. Если вы сделаете это, вы не сможете узнать, произошел ли сбой при поиске, потому что логин не существовал или пользователь ввел неправильный пароль.

Конечно, вы не должны сообщать пользователю, что вызвало неудачную попытку входа в систему, но вам может потребоваться знать, чтобы вы могли регистрировать подозрительные действия.


@ Хавьер говорит в своем ответе, что вы не должны извлекать пароль (или хэш пароля в этом случае) из базы данных. Я не согласна

Хавьер показывает вызов md5() в коде PHP и отправку полученной хеш-строки в базу данных. Но это не поддерживает соление пароля легко. Вы должны сделать отдельный запрос, чтобы получить соль этого пользователя, прежде чем вы сможете сделать хеш в PHP.

Альтернативой является отправка пароля в виде открытого текста по сети из приложения PHP на сервер базы данных. Любой, кто прослушивает вашу сеть, может увидеть этот пароль. Если вы регистрируете SQL-запросы, пароль может увидеть любой, кто получит доступ к журналам. Мотивированные хакеры могут даже погрузиться в мусорную корзину, чтобы найти старые носители с резервной копией файловой системы, и могут читать файлы журналов таким образом!

Меньший риск - извлечь строку хэша пароля из базы данных в приложение PHP, сравнить ее с хэшем ввода пользователя (также в коде PHP), а затем отбросить эти переменные.

2 голосов
/ 28 января 2009

Во-первых, убедитесь, что вы правильно экранировали свои переменные перед использованием их в запросе - используйте mysql_real_escape_string ().

Тогда почему бы не использовать функцию MySQL MD5 для проверки правильности имени входа в вашем запросе?

SELECT login FROM customer WHERE login='$login' AND password = MD5('$password')

Затем просто используйте mysql_num_rows () для подсчета количества возвращаемых строк.

1 голос
/ 28 января 2009

некоторые баллы:

  • НЕ вставлять строковые данные в строку запроса. Особенно предоставленные пользователем данные. что произойдет, если я войду в систему с помощью "Robert '; drop table customer" ?. Используйте либо escape-подпрограммы, либо (гораздо лучше) используйте подготовленные операторы и параметры привязки.
  • НЕ храните пароли в виде открытого текста в вашей базе данных. (ты в порядке)
  • НЕ восстанавливать пароли из вашей базы данных.

что я обычно делаю, это что-то вроде:

$q = preparestatement ("SELECT id FROM customer WHERE login=? AND password=?");
bindvalue ($q, $_POST['login']);
bindvalue ($q, md5($_POST['password']));
$id = execprepared ($q);

if($id) {
    echo "You did it.";
} else {
    echo "Wrong.";
}
0 голосов
/ 30 декабря 2016

Больше, чем PHP 5.6, вы можете использовать функцию hash_compare.

 $users_password = hash(sha256,$salt.$post_password);

 if (hash_equals($users_dbpassword, $users_password)) {
      //pass is good
 } else {
       // pass failed
 }

http://php.net/manual/ru/function.hash-equals.php

0 голосов
/ 13 октября 2013

Получить пароль от пользователя из метода FORM POST и преобразовать $ _POST ['password'] // из формы // в соответствующий формат в php / jsp / any other, а затем сравнить с отформатированным паролем в вашей базе данных

Обычно шифрование md5 используется, когда вы можете сравнить md45 ('{$ _ POST [' password ']}') = присутствует в вашей БД; или обычно mysql использует команду password ('your password') при создании пароля, поэтому сначала соберите $ _POST ['password'] в mysqli_query и mysqli_fetch_array, чтобы получить зашифрованное значение пароля, а затем сравнить.

...