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

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

  • автор:

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

Хеширование — это шифрование короткой строки. В результате получается другая строка определённой длины, например 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 с автоматической солью – то удачи ему �� . Такие пароли, в данный момент времени, считаются надежными.

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

PHP hash: хэширование паролей в PHP

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

В этой статье будет рассмотрен процесс хэширования паролей (hashing) — процесс несложный, но, к сожалению, порой игнорируемый веб-программистами.

Да, хэширование панацеей не является, но всё же при краже данных оно может существенно снизить ущерб. Ведь что собой представляет хэш-функция (hash, хэш, хеш)? Речь идёт о функции, которая обладает бесконечной областью определения, имея при этом конечную область значения. А ещё функции типа hash присуща одна интересная особенность: даже в случае небольшого изменения входного значения у хэш-функции, итоговое значение изменится просто радикально. Если говорить языком криптографию, стоит отметить главное назначение хэш-функций — генерация ключей на основе запоминаемых и коротких паролей (лично вам, легко ли было бы запомнить 16 шестнадцатеричных разрядов?) То-то же.

Подытожив первую часть статьи, скажем, что hash генерирует хэш-код.

Описание hash в PHP

Описать хэш (хеш) в PHP можно следующим образом:

 
hash ( string $algo , string $data [, bool $raw_output = FALSE ] ) : string

Теперь стоит рассказать про список параметров функций типа hash (хеш, хэш): • algo. Тут прописывается название алгоритма, выбранного для хэширования (тот же md5 или SHA-1). Существует целый список поддерживаемых алгоритмов, найти который не составляет труда; • data. Сообщение для хэширования. Без комментариев; • raw_output. Если этот параметр установлен в режим TRUE, то осуществляется вывод необработанных двоичных данных. Если же выставить его в FALSE, производится вывод данных в шестнадцатеричной кодировке (плюс это осуществляется в нижнем регистре).

Возвращаемые значения

При работе функции hash выполняется возврат строки, содержащей вычисленный код в нижнем регистре и в шестнадцатеричной кодировке. Но если raw_output будет задан как TRUE, произойдёт возврат кода в виде бинарных данных.

PHP хэш: хэширование MD5

В качестве продолжения статьи, стоит отдельно поговорить про хэширование по алгоритму MD5. Это будет неплохой пример, да и тема эта в целом весьма важна, а чтение не займёт у вас много времени. Но для начала скажем пару слов о самом алгоритме. MD5 (Message Digest 5) представляет собой 128-битный алгоритм хеширования, который был разработан Рональдом Ривестом в далёком 1991 г. Описан он в RFC 1321 (RFC, если не знаете, — это «Request for Comments» — техническая спецификация и стандарт, широко применяемый в глобальной сети).

Простейший пример практического применения хэша MD5 — шифрование пользовательских паролей. Как уже было сказано, хранить пароли в БД в открытом виде не просто моветон, а в принципе недопустимо. И вот здесь как раз и может прийти на помощь функция хэширования в PHP и соответствующий алгоритм.

В языке программирования PHP функция хэширования MD5 называется md5() . Она принимает одну строку, которую надо зашифровать. Возвращает же MD5-хэш (hash). На практике это может выглядеть следующим образом:

Если вы запустите этот скрипт, увидите MD5-хэш, который будет соответствовать строке "Password".

Теперь простейший скрипт для проверки пароля и логина:

Если вы теперь перейдёте по ссылке "http://путь_к_скрипту.php?login=Admin&password=Password", вы увидите: "Добро пожаловать!".

Свойства MD5

У вышерассмотренного алгоритма есть следующие свойства: • hash содержит 32 символа; • hash уникален для каждой строки; • сам процесс MD5-хэширования является необратимым; • этот процесс отличается достаточной медлительностью.

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

Но если мы пойдём дальше, то увидим, что пункт номер 4 в нашем списке — это тоже плюс, как бы это не звучало парадоксально. Дело в том, что если человек, набирающий пароль, вынужден подождать 0,001 секунды (именно столько и длится процесс), то для него это не проблема — он от этого не пострадает и даже не заметит этой самой медлительности. Если же мы говорим про хакера, которому надо перебрать множество вариантов, то медлительность алгоритма придётся ему очень не кстати, ведь алгоритм задаёт предел — 1000 паролей в секунду. Да, многое зависит и от быстродействия сервера, но несмотря на это, низкая скорость при получении хеша MD5 — это всё-таки проблема для злоумышленника.

На этом закончим и в очередной раз напомним: никогда не храните ваши пароли и пароли ваших пользователей в открытом виде — просто забудьте, что так можно делать, даже (и тем более) если вы обычный веб-мастер. Всегда отправляйте ваши пароли в БД в виде hash (алгоритм выбирайте на своё усмотрение) и сравнивайте не сами пасворды, а их хэши.

Интересует PHP? Добро пожаловать на курс:

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

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