Подтвердить что ты не робот

Использование функции PHP 5.5 password_hash и password_verify

Скажем, я хотел сохранить пароль для пользователя, будет ли это правильным способом сделать это с помощью функции PHP 5.5 password_hash() (или этой версии для PHP 5.3.7+: https://github.com/ircmaxell/password_compat)?

$options = array("cost" => 10, "salt" => uniqid());
$hash = password_hash($password, PASSWORD_BCRYPT, $options);

Тогда я бы сделал:

mysql_query("INSERT INTO users(username,password, salt) VALUES($username, $hash, " . $options['salt']);

Вставить в базу данных.

Тогда для проверки:

$row = mysql_fetch_assoc(mysql_query("SELECT salt FROM users WHERE id=$userid"));
$salt = $row["salt"];
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10, "salt" => $salt));

if (password_verify($password, $hash) {
    // Verified
}
4b9b3361

Ответ 1

Игнорируя проблемы с вашими заявлениями о базе данных, я отвечу на вопрос о password_hash.

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

Функция password_hash возвращает строку, содержащую как хэш, так и соль. Итак:

$hashAndSalt = password_hash($password, PASSWORD_BCRYPT);
// Insert $hashAndSalt into database against user

Тогда для проверки:

// Fetch hash+salt from database, place in $hashAndSalt variable
// and then to verify $password:
if (password_verify($password, $hashAndSalt)) {
   // Verified
}

Кроме того, как следует из комментариев, если вы заинтересованы в безопасности, вы можете посмотреть mysqli (ext/mysql устарел в PHP5.5), а также эту статью о SQL-инъекции: http://php.net/manual/en/security.database.sql-injection.php

Ответ 2

Использование вашей соли не рекомендуется, а с PHP 7 его использование устарело. Чтобы понять, почему, читайте мысли автора

Одна вещь стала для меня совершенно понятной: солевой вариант опасно. Я еще не видел единственного использования опции соли, которая были даже достойными. Каждое использование варьируется от плохого (прохождение mt_rand() вывода) на опасные (статические строки) до безумного (передача пароля как его собственная соль).

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

Ответ 3

Обратите внимание на это из php.net

Внимание

Опция salt устарела с PHP 7.0.0. Сейчас предпочитает просто использовать соль, которая генерируется по умолчанию.

Вывод? Забудьте о солевом варианте.

Этого было бы достаточно password_hash('password', PASSWORD_DEFAULT) * (или _BCRYPT)

Ответ 4

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

Вставьте в базу данных (или файл или все, что вы используете) всю строку, возвращаемую функцией. это содержит: идентификатор алгоритма, стоимость, соль (22 символа) и пароль хэша.

Для использования функции password_verify() требуется вся строка. Соль случайна и не вредит попадать в чужие руки (с хэшированным паролем). Это предотвращает (или очень сложно) использование готовых наборов генерируемых списков паролей и хэшей - радужных таблиц.

Вам следует рассмотреть возможность добавления параметра стоимости. По умолчанию (если опущено) - 10 - если выше, то функция вычисляет хэш дольше. Увеличение стоимости на 1, удвоенное время, необходимое для генерации хэша (и, следовательно, удлинение времени, необходимого для нарушения пароля)

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10));

вы должны установить этот параметр на основе проверки скорости на вашем сервере. Рекомендуется, чтобы функция выполняла 100 мс + (некоторые предпочитают делать 250 мс). Обычно стоимость = 10 или 11 является хорошим выбором (в 2015 году).

Чтобы повысить безопасность, вы можете добавить в пароли длинную (50-60 символов - хороший выбор) секретную строку. прежде чем вы будете использовать password_hash() или password_verify().

$secret_string = '[email protected]#[email protected]#$234';
$password  = trim($_POST['user_password']) . $secret_string;
// here use password_* function

Внимание Использование параметра PASSWORD_BCRYPT для параметра algo приведет к усечению параметра пароля до максимальной длины 72 символа.

Если пароль $будет длиннее 72 символов, и вы измените или добавите 73 или 90 символов, хэш не изменится. Необязательно, приклеивание $secret_string должно быть в конце (после пароля пользователя, а не раньше).