РНР-безопасность: где и как хранить пароли. Часть 2

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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

Одной из главных претензий было отсутствие в статье упоминания password_hash, как мы и обещали, вторую часть данного материала начнем как раз таки с хеширования пароля с помощью password_hash. Также напоминаем о том, что написание данной статьи было навеяно запуском новой группы по курсу «Backend-разработчик на PHP», но к программе обучения данный материал отношения не имеет.


Подробнее о программе обучения можно будет узнать на дне открытых дверей, а на примере бесплатного вебинара по теме «ServerLess PHP», вы можете оценить формат проведения лекций.

Пожалуй на этом мы завершим и без того затянувшееся предисловие и перейдем непосредственно к статье.

Хеширование пароля с помощью password_hash


Эта функция создает хеш пароля в соответствии с теми параметрами, которые мы ей зададим. Она использует односторонний алгоритм.

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

  • PASSWORD_DEFAULT из PHP 5.5 использует Bcrypt в качестве алгоритма по умолчанию. Однако с течением времени это изменяется по мере обнаружения новых, более безопасных алгоритмов либо иных факторов.
  • PASSWORD_BCRYPT создает хеш crypt(). Обычно он содержит 60 символов, опознать его можно по идентификатору в формате "$2y$".
  • PASSWORD-ARGON2I Argon2 на данный момент является одним из наиболее безопасных алгоритмов хеширования. Он доступен только в том случае, если РНР был скомпилирован с Argon2.
  • PASSWORD_ARGON2ID Этот алгоритм хеширования также принадлежит к семейству Argon2 и задействует версию Argon2ID, а не I. Чтобы он работал, также необходимо, чтобы РНР был скомпилирован посредством Argon2.

У этой функции также есть необязательный параметр, который состоит из ассоциативного массива, принимающего несколько ключей в соответствии с выбранным алгоритмом.
Если вы предпочитаете использовать Bcrypt, ключ этой последовательности будет значением cost.

Если вы выберете алгоритм, который использует Argon2, ключами для ассоциативного массива будут: memory_cost (целое число, указывающее максимальное количество памяти, необходимое для вычисления хэша), time_cost (целое число, указывающее максимальное время, необходимое для вычисления хэша) и thread (другое целое число, указывающее количество потоков, используемых при вычислении хэша).

Не указывайте параметр salt в РНР 7.0, иначе получите предупреждение об устаревшем подходе.

Теперь мы знаем, какие элементы необходимы для использования функции password_hash(). Давайте посмотрим, как ее прописывать.

echo password_hash("MySuperPass", PASSWORD_DEFAULT);
$2y$10$TLayAY8ZaAZ9FE50EylGYO9oEgrb7gsw1yzJemHdBu1gOQfyWrEUm
$options = ['cost' => 12,];

echo password_hash("MySuperPass", PASSWORD_BCRYPT, $options);
$2y$12$jhmTbxAuZXVtX2y.Jc8iy.dW/NENqVCeq2vuoFI9/oa4./YlzhpYO

echo password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
$argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0

Сначала рекомендуется протестировать эту функцию на ваших серверах и настроить параметр cost таким образом, чтобы исполнение функции отнимало менее 100 миллисекунд в интерактивных системах.

Скрипт в вышеприведенном примере поможет вам задать оптимальное значение cost для вашего аппаратного оборудования.

Верификация пароля пользователя


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

Хешируя данные в соответствии с последними трендами безопасности, вы ничего не храните в зашифрованном виде, а ваш сервер спрятан в подвале 10-метровой глубины.

Что теперь?

Теперь вы должны позволить пользователям залогиниться в приложении. Для этого в РНР предусмотрена встроенная функция, которая проверяет соответствие пароля хешированной последовательности. Эта функция носит название password_verify(). Работает она примерно вот так:

$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Пароль верен!';
} else {
    echo 'Пароль не правильный!';
}

У нее есть два параметра, и оба должны иметь формат последовательности. Первый параметр — это пароль, который пользователь ввел в форму входа в аккаунт. Второй параметр — это непосредственно хешированные данные, с которыми мы будем сверяться.

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

Эта функция работает благодаря тому, что на предыдущем шаге (когда мы хешировали пароль), значение, вернувшееся от password_hash, включало в себя используемый нами алгоритм, cost и salt.

Таким образом, нам доступна вся информация, необходимая для password_verify().

Алгоритм работы системы регистрации пользователей на РНР


Надеюсь, теперь вы понимаете, какие меры безопасности принимают РНР-разработчики при обращении с паролями.

Сначала необходимо проверить наличие post-запроса, а затем отобрать и подсчитать количество пользователей, чьи данные совпадают с введенными.

Если все прошло успешно, мы верифицируем пароль и отправляем пользователя на стартовую страницу. В противном случае, например, на Javascript выводим окно предупреждения с оповещением об ошибке.

Заключение


Теперь вы знаете, как обеспечить безопасность своему приложению и как правильно обращаться с паролями. Следование полезным рекомендациям — это не просто стандарт, который вы должны соблюдать, а путь развития, следовать которому должно быть приятно.
Осваивайте новые техники по аналогии с тем, как вы только что ознакомились. Добавляйте дополнительный функционал и экспериментируйте с кодом до тех пор, пока не получите отличные скиллы по веб-разработке — будь то РНР или любой другой язык, открывающий перед вами не менее широкие возможности!

Читать первую часть
Источник: https://habr.com/ru/company/otus/blog/475874/

Интересные статьи

Интересные статьи

Я живу в своем доме. До недавнего времени мы всей своей большой дружной семьей ютились на первом этаже двухэтажного дома. Время шло, а этаж так и не хотел превращаться в ...
В предыдущих статьях мы разобрались с основами среды и достаточно подробно изучили язык программирования Microsoft PowerShell. Завершая цикл, мы рассмотрим работу с процессами и с...
За прошлый год я собрал и настроил автоматизацию для небольшой квартиры около оживленной дороги. В этой статье я расскажу об использованных решениях в климатической системе, освещении, мультимеди...
Computer Science Center — это совместная инициатива Computer Science клуба при ПОМИ РАН, компании JetBrains и Школы анализа данных Яндекса. Центр существует, чтобы дать возможность талантливым...
Сегодня мы публикуем вторую часть перевода материала о расширении синтаксиса JavaScript с использованием Babel. → Головокружительная первая часть