Как расхешировать пароль php
Перейти к содержимому

Как расхешировать пароль php

  • автор:

Хеширование пароля на PHP

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

Поэтому обычно логин хранится в открытом виде, а пароль хешируется специальной функцией md5 , которая параметром принимает пароль, а возвращает его , по которому нельзя восстановить этот самый пароль.

Давайте, например, найдем хеш какой-нибудь строки:

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

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

Описанная правка будет представлять собой что-то такое:

Внесем аналогичные правки в авторизацию:

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

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

Хеширование паролей

Хеширование — это шифрование короткой строки. В результате получается другая строка определённой длины, например 32 символа. Обычно делают хэширование паролей. Способов расшифровки хешированного пароля нет. Возможен только подбор. Поэтому хранение паролей в таком виде безопаснее, чем в обычном.

В PHP есть несколько функций для хэширования строки. Раньше самой распространённой была функция md5() . Но она работает слишком быстро и позволяет достаточно быстро подобрать пароль. Поэтому использовать её нежелательно. Наиболее удобной функцией является password_hash() с алгоритмом хеширования PASSWORD_BCRYPT . Она возвращает строку в зашифрованном виде.

password_hash (пароль, алгоритм, настройки)

пароль — пароль, который хешируется

алгоритм — алгоритм хеширования. Принимает значения: PASSWORD_DEFAULT и PASSWORD_BCRYPT.

настройки — настройки функции. Их менять не рекомендуется

$pas_reg = 'Ivan11'; //пароль, указанный при регистрации $hash = password_hash($pas_reg, PASSWORD_BCRYPT); echo $hash;

Запустите скрипт и посмотрите, как выглядит хешированная строка.

Когда пользователь авторизуется на сайте и вводит пароль, его нужно сравнить с хэшированной строкой. Для этого есть функция password_verify() . Она возвращает true , если строка совпадает с паролем, зашифрованным функцией password_hash() , и false , если строка не соответствует паролю.

password_verify (пароль, хешированная строка)

пароль — пароль, введённый пользователем

хешированная строка — строка, с которой сравнивается пароль

Добавим в скрипт проверку введённого пароля:

$pas_login = 'Ivan11'; //пароль, введённый при авторизации $pr = password_verify($pas_login, $hash); if ($pr) echo '
совпадает'; else echo '
не совпадает';

При хешировании применяется соль. Эта информация не имеет практического значения, потому что функция password_hash() добавляет соль автоматически. Но Вы можете встретить этот термин, и нужно знать, что он означает. Соль — это набор символов, который добавляется к паролю перед хешированием. Она используется потому, что есть возможность расшифровать строку. Это делают с помощью баз данных, которые содержат огромное количество паролей и соответствующих им хешированных строк. Использование соли делает расшифровку сложнее. Расшифрованная строка не совпадает с паролем, потому что она имеет лишние символы. Авторизоваться с помощью расшифрованной строки не получится, она не соответствует паролю.

Хеширование обычно применяется в функциях регистрации и авторизации пользователей.

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

Коприрование материалов сайта возможно только с согласия администрации

2017 — 2024 © basecourse.ru Все права защищены

Безопасное хеширование паролей

В этом разделе разъясняются причины, стоящие за хешированием паролей в целях безопасности, а также эффективные методы хеширования.

  1. Почему я должен хешировать пароли пользователей в моем приложении?
  2. Почему популярные хеширующие функции, такие как md5 и sha1 не подходят для паролей?
  3. Если популярные хеширующие функции не подходят, как же я тогда должен хешировать свои пароли?
  4. Что такое соль?
  5. Как я должен хранить свою соль?

Почему я должен хешировать пароли пользователей в моем приложении?

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

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

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

Почему популярные хеширующие функции, такие как md5() и sha1() не подходят для паролей?

Такие хеширующие алгоритмы как MD5, SHA1 и SHA256 были спроектированы очень быстрыми и эффективными. При наличии современных технологий и оборудования, стало довольно просто выяснить результат этих алгоритмов методом «грубой силы» для определения оригинальных вводимых данных.

Из-за той скорости, с которой современные компьютеры могут «обратить» эти хеширующие алгоритмы, многие профессионалы компьютерной безопасности строго не рекомендуют использовать их для хеширования паролей.

Если популярные хеширующие функции не подходят, как же я тогда должен хешировать свои пароли?

При хешировании паролей существует два важных соображения: это стоимость вычисления и соль. Чем выше стоимость вычисления хеширующего алгоритма, тем больше времени требуется для взлома его вывода методом «грубой силы».

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

При хешировании паролей рекомендуется применять алгоритм Blowfish, который также используется по умолчанию в API хеширования паролей, так как он значительно большей вычислительной сложности, чем MD5 или SHA1, при этом по-прежнему гибок.

Учтите, что, если вы используете функцию crypt() для проверки пароля, то вам нужно предостеречь себя от атак по времени, применяя сравнение строк, которое занимает постоянное время. Ни операторы PHP == и ===, ни функция strcmp() не являются таковыми. Функция же password_verify() как раз делает то, что нужно. Настоятельно рекомендуется использовать встроенное API хеширования паролей, если есть такая возможность.

Что такое соль?

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

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

password_hash() создаёт случайную соль в случае, если она не была передана, и чаще всего это наилучший и безопасный выбор.

Как я должен хранить свою соль?

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

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

PHP – всё про защиту пароля

Сейчас множество сайтов требуют авторизацию, используя в качестве логина email, и реже – телефон. Но как хранится ваш пароль в базе данных? Действительно ли это безопасно и может ли владелец сайта воспользоваться этими данными? Давайте разбираться.

PHP – md5 вычисляем хеш строки

Строки? А почему не пароля?
НЕ ИСПОЛЬЗУЙТЕ md5 для “шифрования” паролей, это очень ненадежное средство. Как это выглядит на практике:

echo md5('test123'); // cc03e747a6afbbcbf8be7668acfebee5 echo md5('test124'); // ad2af2578b4d55b5f78383024270f852

Если запустить данную команду, то функция вернёт MD5-хеш строки. У нас два разных пароля, у которых отличается только последний символ test123 и test124. Разница 1 символ, но ничего общего в хеше md5 нет.

Так почему же такой способ ненадежный? Он очень легко ломается, и если вы не можете перевести обратно из md5 в текст, то для злоумышленника это не займет много времени (что уж там говорить, если есть сайты, которые это делают в пару кликов).

Предположим, что md5 это хороший и надежный способ хранить пароли (напомню, это не так). Как бы тогда выглядел код?

$passwordHash = ‘cc03e747a6afbbcbf8be7668acfebee5’; $password = $_REQUEST[‘password’]; if (md5($password) === $passwordHash) < echo 'done'; >else

Где, $passwordHash – это зашифрованный пароль, который лежит в базе данных, а $password = $_REQUEST[‘password’] – это пароль, который ввел пользователь через форму авторизации.

PHP – Как надежно защитить пароль?

Для этого нам понадобится функция password_hash и password_verify. Как вообще должен храниться пароль:

При таком указании пароля он делится на части:
алгоритм – при помощи которого и был зашифрован пароль;
cost – задаёт необходимую алгоритмическую сложность, стандартно она 10, чем выше сложность, тем дольше будет генерироваться пароль, и соответственно, тем дольше будет загружаться страница;
salt – соль для хеширования, некая уникальная строка, которая увеличивает сложность дешифровки пароля. На данный момент, используется автоматическая соль, но об этом чуть ниже;
хэш – хэш пароля.

То есть, пароль шифруется при помощи определенного алгоритма, сложности и соли.

Как применять функцию password_hash в PHP?

Функция должна содержать 2 аргумента, сам пароль и алгоритм. PASSWORD_DEFAULT, PASSWORD_BCRYPT – наиболее чаще встречаются в качестве алгоритмов, особенно PASSWORD_BCRYPT. Такой хэш пароля, в отличие от md5, при перезагрузке страницы, всегда будет уникальным, и его длина, независимо от выбранной сложности, всегда 60 символов.
Выглядит это следующим образом:

echo password_hash('test123', PASSWORD_DEFAULT); // $2y$10$kPuLknA408BkgnaKVUh8EOQOm1dRUUkufeqvG6OoIvpGDopPGea1q echo password_hash('test123', PASSWORD_BCRYPT); // $2y$10$jFmerATwXASg0WvV3W9pt.fK1UQmnnLrKao35r6/VJfzz7NPxszCq echo mb_strlen(password_hash('test123', PASSWORD_BCRYPT)); // 60

Как же нам увеличить сложность алгоритма? Для этого нужно использовать третий аргумент функции, который не обязательный, это опции:

echo password_hash('test123', PASSWORD_BCRYPT, ['salt' => 'ttttttttttttttttttttttttt']); // $2y$10$ttttttttttttttttttttteRXxHYSDzcdOi/S1JzEheCNMETevWiKC echo password_hash('test123', PASSWORD_BCRYPT, ['cost' => 12]); // $2y$12$wNh3cx81xQzXvOKCwPuerOOBOyyxgE3noJQsp3L3RYDMy43CTs4n2

Через массив мы указываем salt – и она уже будет являться частью строки. Если вы внимательно изучите сам процесс создания этого участка “из соли”, то обнаружите, что она может записаться не полностью, или может быть не достаточно сложной. В настоящее время не рекомендуется её задавать явно, а начиная с PHP 8 её просто игнорируют, и всё равно генерируют автоматически.

Внимание
Эта опция объявлена устаревшей. Рекомендуется использовать автоматически генерируемую соль. Начиная с PHP 8.0.0 явно заданная соль игнорируется.

Теперь что касается cost, и сложности хэша. Как и говорилось выше, чем больше сложность, тем больше потребуется ресурсов для генерации. Чтобы вычислить оптимальную сложность, можно воспользоваться функцией из документации:

/** * Данный код замерит скорость выполнения операции хеширования для вашего сервера * с разными значениями алгоритмической сложности для определения максимального * его значения, не приводящего к деградации производительности. Хорошее базовое * значение лежит в диапазоне 8-10, но если ваш сервер достаточно мощный, то можно * задать и больше. Данный скрипт ищет максимальное значение, при котором * хеширование уложится в 50 миллисекунд. */ $timeTarget = 0.05; // 50 миллисекунд. $cost = 8; do < $cost++; $start = microtime(true); password_hash("test", PASSWORD_BCRYPT, ["cost" =>$cost]); $end = microtime(true); > while (($end - $start) < $timeTarget); echo "Оптимальная стоимость: " . $cost;

Как проверить хэш пароля в PHP?

Делается это при помощи специальной функции, password_verify:

$hash = '$2y$10$ttttttttttttttttttttteRXxHYSDzcdOi/S1JzEheCNMETevWiKC'; if (password_verify('test124', $hash)) < echo 'done'; >else

Пара моментов на которые стоит обратить внимание:
1. Один и тот же пароль, зашифрованный при помощи функции password_hash, всегда будет иметь разный хеш, но при этом, password_verify – раскодирует его именно так как нужно.
2. От одной версии языка PHP к другой, с течением времени, с изменением общей ситуации в мире безопасности, да и вообще, в контексте разного “железа” на вашем сервере, нужно думать наперед, и писать код через password_needs_rehash.

Что такое password_needs_rehash?

password = 'rasmuslerdorf'; $hash = '$2y$10$YCFsG6elYca568hBi2pZ0.3LDL5wjgxct1N8w/oLR/jfHsiQwCqTS'; // Параметр стоимости может изменяться в связи со сменой оборудования $options = array('cost' => 11); // Проверка сохранённого хеша с помощью пароля if (password_verify($password, $hash)) < // Проверяем, не нужно ли использовать более новый алгоритм // или другую алгоритмическую стоимость if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) < // Если таки да, перехешируем и сохраняем новый хеш $newHash = password_hash($password, PASSWORD_DEFAULT, $options); >// Авторизуем пользователя >

Опять же, замечательный пример из документации, который будет создавать новый хэш пароля, вам нужно будет перезаписать его в базе данных, в случае таких вот изменений обстоятельств, которые описаны в пункте 2. Изменили ‘cost’ => 13, пожалуйста, вот вам новый пароль).
Долго загружается страница, вернулись на стандартные 10, и снова всё автоматически работает, песня! �� .

И всё таки, может ли владелец сайта расшифровать такой пароль? Ответ – если это md5 или base65, да, запросто, если это password_hash с автоматической солью – то удачи ему �� . Такие пароли, в данный момент времени, считаются надежными.

На этом всё, надеюсь было интересно �� .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *