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

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

Авторизоваться:

require_once __DIR__.'/config.php';
session_start();

$dbh = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_USERNAME, DB_USERNAME, DB_PASSWORD);

$sql = "SELECT * FROM users WHERE username = :u AND password = :p";
$query = $dbh->prepare($sql); // prepare
$params = array(":u" => $_POST['username'], ":p" => $_POST['password']);
$query->execute($params); // execute

$results = $query->fetchAll(); // then fetch


//hash passwords pls

if (count($results) > 0 ){
$firstrow = $results[0];
$_SESSION['username'] = $firstrow['username'];
echo "Hello $username you have successfully logged in";
//header ("location:.php");
}
else{
echo "Login Has Failed";
return;
} 

Регистр:

$dbh = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_USERNAME, DB_USERNAME, DB_PASSWORD);

$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];

$stmt = $dbh->prepare("insert into users set username='".$username."', email='".$email."', password='".$password."' ");
$stmt->execute();
echo "<p>Thank you, you are registered</p>";

Может ли кто-нибудь показать мне, как включить его в код, который у меня есть?


person stark    schedule 21.04.2015    source источник
comment
Соответствует ли PHPass вашим потребностям? Что касается регистрации, вы проверяете оба хэша во время аутентификации и применяете нужный хеш во время создания учетной записи.   -  person Answers_Seeker    schedule 21.04.2015
comment
примечание: ваша часть регистра небезопасна. Готов поспорить, я смогу найти вам 50 ссылок, связанных с этим, за 5 минут. но это твоя работа. покажи нам, что ты пробовал.   -  person Funk Forty Niner    schedule 21.04.2015
comment
Проверьте password_hash(). Он встроен прямо в новые версии PHP.   -  person ircmaxell    schedule 21.04.2015
comment
@ircmaxell давайте не будем забывать ваш password_hash() compatibility pack на всякий случай ;-)   -  person Funk Forty Niner    schedule 21.04.2015


Ответы (3)


Просто используйте библиотеку. Серьезно. Они существуют по причине.

  • PHP 5.5+: используйте password_hash()
  • PHP 5.3.7+: используйте password-compat (пакет совместимости для вышеуказанного)
  • Все остальные: используйте phpass.

Не делай этого сам. Если вы создаете собственную соль, ВЫ ДЕЛАЕТЕ ЭТО НЕПРАВИЛЬНО. Вы должны использовать библиотеку, которая сделает это за вас.

$dbh = new PDO(...);

$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$hash = password_hash($password, PASSWORD_DEFAULT);

$stmt = $dbh->prepare("insert into users set username=?, email=?, password=?");
$stmt->execute([$username, $email, $hash]);

И при входе:

$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $dbh->prepare($sql);
$result = $stmt->execute([$_POST['username']]);
$users = $result->fetchAll();
if (isset($users[0]) {
    if (password_verify($_POST['password'], $users[0]->password) {
        // valid login
    } else {
        // invalid password
    }
} else {
    // invalid username
}
person ircmaxell    schedule 21.04.2015
comment
У меня было ощущение, что вы собираете что-то (достойное) воедино. - person Funk Forty Niner; 21.04.2015
comment
+100 за They exist for a reason. - person fresher; 02.11.2016
comment
Вы сравниваете ввод пользователя с сохраненным значением для проверки входа? Это не сработает. Сохраненное значение хэшируется, помните? - person Doug Wolfgram; 08.11.2016

О повышении безопасности кода:

  • Вы должны ВСЕГДА проверять пользовательские записи, даже с помощью метода POST, который можно изменить с помощью firebug перед отправкой формы. Поскольку вы вставляете вводимые пользователем данные в запрос, это гораздо важнее.

О вашем вопросе в целом

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

Вы будете хешировать имя пользователя, пароль и соль во время создания учетной записи и вставлять хэш в базу данных.

Во время аутентификации вы повторно сгенерируете хеш с заданным логином + паролем и информацией, которую вы добавили для создания соли.

Если оба сгенерированных хэша совпадают, пользователь аутентифицируется.

РЕДАКТИРОВАТЬ: Да, password_hash тоже хорош.

person Answers_Seeker    schedule 21.04.2015
comment
Если вы создаете свою собственную соль, вы делаете что-то ужасно неправильное. - person ircmaxell; 21.04.2015

По сути, у вас есть два варианта, различающихся по сложности:

  • Сохраните хэш пароля зарегистрированного пользователя, используя выбранный вами алгоритм хеширования (подробнее об этом позже).
  • создайте случайную соль (постоянную секретную строку), которая будет использоваться вместе с паролем пользователя, для создания хэша, как указано выше, а затем сохраните этот хэш в БД.

Когда вы извлекаете запись пользователя, вы сравниваете хэш, вычисленный из предоставленного пароля, с хэшем, хранящимся в БД.

Пример:

$HashedPass = hash('sha512', $password);

или с предопределенной SALT:

$HashedPass = hash('sha512', $password.SALT_STRING);

Сохраните это в БД, как и раньше.

Аутентификация делается аналогично:

$HashedPass = hash('sha512', $password.SALT_STRING);

а затем получить из БД на основе сравнения этого хэша с сохраненным.

Теперь я хотел бы ответить на ваши опасения по поводу алгоритмов хеширования: вам не обязательно использовать md5, вы также можете использовать более безопасные алгоритмы хеширования, см. комментарий здесь: Хеш-функция PHP Одно из предложений — использовать алгоритм sha512.

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

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

person Carmageddon    schedule 21.04.2015