Хеширование пароля на PHP
Хранить пароль в открытом виде — неправильно. Хакер-злоумышленник может получить доступ к вашей базе данных и украсть пароли.
Поэтому обычно логин хранится в открытом виде, а пароль хешируется специальной функцией md5 , которая параметром принимает пароль, а возвращает его , по которому нельзя восстановить этот самый пароль.
Давайте, например, найдем хеш какой-нибудь строки:
Сейчас нам необходимо переделать нашу регистрацию и нашу авторизацию. Для начала я бы советовал очистить таблицу с юзерами, так как там сейчас хранятся пароли в открытом виде, а должны хранится их хеши. Затем при тестировании регистрации таблица заполнится данными в новом формате.
Давайте теперь поправим нашу регистрацию так, чтобы при сохранении нового пользователя в базу добавлялся не пароль, а его хеш.
Описанная правка будет представлять собой что-то такое:
Внесем аналогичные правки в авторизацию:
Внесите изменения в регистрацию с учетом хеширования, зарегистрируйте пару новых пользователей, убедитесь, что в базу данных они добавились с хешированными паролями.
Внесите изменения в авторизацию с учетом хеширования, попробуйте авторизоваться под зарегистрированными ранее пользователями.
Добавляем соль в регистрацию
Итак, вы уже знаете, что хеширование через md5 — необратимый процесс и хакер, получивший доступ к хешу, не сможет получить по этому хешу пароль.
На самом деле это утверждение не совсем верное — в настоящее время злые хакеры составили библиотеки хешей популярных и не очень паролей и любой дурак может разгадать пароль, просто загуглив его хеш.
Речь идет о достаточно простых, популярных паролях.
Загуглите, например, хеш 827ccb0eea8a706c4c34a16891f84e7b и сразу в поиске гугла вы увидите, что это пароль ‘12345’ .
Хеши достаточно сложных паролей таким образом не разгадать (попробуйте).
Вы можете спросить, в чем тогда проблема — давайте все мы будем регистрироваться со сложными паролями. Есть, однако, проблема — большинство пользователей не задумываются о безопасности своих данных и могут вводить достаточно простые пароли.
Мы можем при регистрации заставлять придумывать более длинные пароли, ограничивая, к примеру, минимальное количество символов 6 -ю или 8 -ю, однако, все равно будут появляться пароли вида ‘123456’ или ‘12345678’ .
Можно, конечно, придумать более умный алгоритм проверки пароля на сложность, но есть другое решение.
Суть этого решения такая: пароли надо . Соль — это специальная случайная строка, которая будет добавляться к паролю при регистрации и хеш уже будет вычисляться не от простого пароля типа, а от строки соль+пароль, то есть от соленого пароля.
То есть при регистрации вы будете делать что-то типа такого:
При этом соль будет разная для каждого пользователя, ее нужно будет генерировать случайным образом в момент регистрации.
Вот готовая функция, которая сделает это:
С помощью этой функции можно переписать наш код вот так:
Еще раз повторю, что это были изменения при регистрации — в БД сохраняем не просто хеш пароля, а хеш соленого пароля.
Это еще не все: в таблице с юзерами кроме поля login и password нужно сделать еще и поле salt , в котором мы будем хранить соль каждого пользователя.
Реализуйте описанную выше регистрацию с соленым паролем.
Добавляем соль в авторизацию
Теперь нам необходимо поменять авторизацию. Здесь уже изменения будут более существенными.
Уже не получится проверить правильность пары логин-пароль сразу же, одним запросом. Почему: потому что, чтобы проверить пароль, надо получить его соленый хеш, а соль хранится в базе данных и уникальная для каждого логина.
Придется вначале получить запись только по логину, прочитать соль, посолить введенный пароль и сравнить с соленым паролем из базы и только, если они совпадают, — авторизовывать пользователя.
Учтите, что может такое быть, что логин вбит неправильно, в этом случае проверку пароля можно не осуществлять, а сразу вывести, что авторизация не возможна — данные не верны:
Давайте добавим проверку пароля:
В целях безопасности пользователю обычно не сообщают, что именно не подошло — логин или пароль, чтобы усложнить подбор пар логин-пароль хакерами. Просто выводят сообщение о том, что пара логин-пароль неверна или что-то в таком роде.
Реализуйте описанную выше авторизацию с соленым паролем. Попробуйте зарегистрируйтесь, авторизуйтесь, убедитесь, что все работает.
Используем функцию password_hash
На самом деле функция md5 и соление пароля с ее помощью считается устаревшим. Мы изучали ее, чтобы вы поняли дальнейший материал, а также потому, что вы можете столкнуться с этим, работая с чужими проектами.
Существует более совершенный способ получить соленый пароль. Для этого используется функция password_hash . Первым параметром она принимает строку, а вторым — алгоритм шифрования (о нем позднее), и возвращает хеш этой строки вместе с солью.
Попробуйте несколько раз запустите этот код:
Вы каждый раз будете получать разный результат и в этом результате первая часть строки будет являться солью, а вторая часть — соленым паролем.
Пусть у нас есть хеш, полученный из функции password_hash и какой-то пароль. Чтобы проверить, это хеш этого пароля или нет, следует использовать функцию password_verify — первым параметром она принимает пароль, а вторым — хеш, и возвращает true или false .
Давайте посмотрим на примере:
Что это дает нам на практике: мы можем не создавать в базе данных отдельное поле для хранения соли, не заморачиваться с генерированием этой соли — PHP все сделает за нас!
То есть получится, что в базе данных в поле password мы будем хранить соленый пароль вместе с его солью. При этом хешированный пароль будет иметь большую длину. Поэтому в базе данных нам нужно исправить размер поля с паролем и установить ее в 60 символов.
Теперь давайте поправим код регистрации. Вот то, что есть сейчас:
С помощью password_hash мы сократим это до:
Аналогичным образом подправится код авторизации:
Переделайте вашу авторизацию и регистрацию на новые изученные функции.
В настоящее время алгоритмом по умолчанию будет алгоритм BCrypt (то есть аналог md5, но мощнее), который своим результатом возвращает строку соль+хеш размером 60 символов.
Это значит, что поле password в базе данных следует установить такого размера — 60 символов, иначе ничего не будет работать верно.
Алгоритм BCrypt можно указать явно во втором параметре функции password_hash , написав там PASSWORD_BCRYPT .
Если же оставить там PASSWORD_DEFAULT — то PHP возьмет алгоритм по умолчанию, то есть тот же BCrypt — но это в настоящее время. В будущем возможно BCrypt устареет также, как и md5 и будет заменен более мощным алгоритмом.
В таком случае изменения в вашем коде произойдут автоматически при переходе на новую версию PHP.
PHP – всё про защиту пароля
Сейчас множество сайтов требуют авторизацию, используя в качестве логина email, и реже – телефон. Но как хранится ваш пароль в базе данных? Действительно ли это безопасно и может ли владелец сайта воспользоваться этими данными? Давайте разбираться.
PHP – md5 вычисляем хеш строки
Строки? А почему не пароля?
НЕ ИСПОЛЬЗУЙТЕ md5 для “шифрования” паролей, это очень ненадежное средство. Как это выглядит на практике:
Если запустить данную команду, то функция вернёт MD5-хеш строки. У нас два разных пароля, у которых отличается только последний символ test123 и test124. Разница 1 символ, но ничего общего в хеше md5 нет.
Так почему же такой способ ненадежный? Он очень легко ломается, и если вы не можете перевести обратно из md5 в текст, то для злоумышленника это не займет много времени (что уж там говорить, если есть сайты, которые это делают в пару кликов).
Предположим, что md5 это хороший и надежный способ хранить пароли (напомню, это не так). Как бы тогда выглядел код?
Где, $passwordHash – это зашифрованный пароль, который лежит в базе данных, а $password = $_REQUEST[‘password’] – это пароль, который ввел пользователь через форму авторизации.
PHP – Как надежно защитить пароль?
Для этого нам понадобится функция password_hash и password_verify. Как вообще должен храниться пароль:
При таком указании пароля он делится на части:
алгоритм – при помощи которого и был зашифрован пароль;
cost – задаёт необходимую алгоритмическую сложность, стандартно она 10, чем выше сложность, тем дольше будет генерироваться пароль, и соответственно, тем дольше будет загружаться страница;
salt – соль для хеширования, некая уникальная строка, которая увеличивает сложность дешифровки пароля. На данный момент, используется автоматическая соль, но об этом чуть ниже;
хэш – хэш пароля.
То есть, пароль шифруется при помощи определенного алгоритма, сложности и соли.
Как применять функцию password_hash в PHP?
Функция должна содержать 2 аргумента, сам пароль и алгоритм. PASSWORD_DEFAULT, PASSWORD_BCRYPT – наиболее чаще встречаются в качестве алгоритмов, особенно PASSWORD_BCRYPT. Такой хэш пароля, в отличие от md5, при перезагрузке страницы, всегда будет уникальным, и его длина, независимо от выбранной сложности, всегда 60 символов.
Выглядит это следующим образом:
Как же нам увеличить сложность алгоритма? Для этого нужно использовать третий аргумент функции, который не обязательный, это опции:
Через массив мы указываем salt – и она уже будет являться частью строки. Если вы внимательно изучите сам процесс создания этого участка “из соли”, то обнаружите, что она может записаться не полностью, или может быть не достаточно сложной. В настоящее время не рекомендуется её задавать явно, а начиная с PHP 8 её просто игнорируют, и всё равно генерируют автоматически.
Внимание
Эта опция объявлена устаревшей. Рекомендуется использовать автоматически генерируемую соль. Начиная с PHP 8.0.0 явно заданная соль игнорируется.
Теперь что касается cost, и сложности хэша. Как и говорилось выше, чем больше сложность, тем больше потребуется ресурсов для генерации. Чтобы вычислить оптимальную сложность, можно воспользоваться функцией из документации:
Как проверить хэш пароля в PHP?
Делается это при помощи специальной функции, password_verify:
Пара моментов на которые стоит обратить внимание:
1. Один и тот же пароль, зашифрованный при помощи функции password_hash, всегда будет иметь разный хеш, но при этом, password_verify – раскодирует его именно так как нужно.
2. От одной версии языка PHP к другой, с течением времени, с изменением общей ситуации в мире безопасности, да и вообще, в контексте разного “железа” на вашем сервере, нужно думать наперед, и писать код через password_needs_rehash.
Что такое password_needs_rehash?
Опять же, замечательный пример из документации, который будет создавать новый хэш пароля, вам нужно будет перезаписать его в базе данных, в случае таких вот изменений обстоятельств, которые описаны в пункте 2. Изменили ‘cost’ => 13, пожалуйста, вот вам новый пароль).
Долго загружается страница, вернулись на стандартные 10, и снова всё автоматически работает, песня! .
И всё таки, может ли владелец сайта расшифровать такой пароль? Ответ – если это md5 или base65, да, запросто, если это password_hash с автоматической солью – то удачи ему . Такие пароли, в данный момент времени, считаются надежными.
How to decrypt md5 password in PHP?
One of the most important parts of a website is the authentication system and it is commonplace for developers to commit mistakes leaving out vulnerabilities for others to exploit. Since PHP is a server-side scripting language, it is responsible for all the back-end functionalities required by the website. In this article, we will learn how to decrypt md5 password in PHP in the following sequence:
- Why do we need MD5 in PHP?
- What is MD5 hashing?
- How to use MD5 in PHP?
- Syntax
- How to Decrypt MD5 Passwords in PHP?
- Examples
Why do we need MD5 in PHP?
One basic example could be storing and using user passwords in its true form, in this situation an unauthorized person might get access to the database and the whole system is compromised. To prevent this situation password hashing is used. Password hashing can be defined as a method that takes the user password or string and encrypts it into a fixed-length password, PHP has a few functions to achieve the same like md5(), sha1(), hash().
What is MD5 hashing?
MD5 hashing algorithm generates a 32 characters string (hexadecimal) for any word or phrase we give in the input. We can even encrypt an entire file into an MD5 hash. The algorithm can also be used for digital signature applications, where a large file is compressed in a secure manner and then encrypted with the help of a private key.
How to use MD5 in PHP?
To calculate the MD5 hash of a string PHP has a pre-defined function md5(). The md5() function calculates the MD5 hash of a string input and returns the hash hexadecimal number. The md5() function uses the MD5 Message-Digest Algorithm.
Syntax:
Return Type:
md5() returns hash as a 32-character hexadecimal number.
How to Decrypt MD5 Passwords in PHP?
The MD5 cryptographic algorithm is not reversible i.e. We cannot decrypt a hash value created by the MD5 to get the input back to its original value. So there is no way to decrypt an MD5 password. But, we can use something like brute force hacking, which is extremely resource-intensive, not practical, and unethical. Thus, if someone is entering the correct password, we need to find the hash value of whatever the user entered, and see if it matches what we have in our database thus it is a time and resource-intensive job to perform.
It is possible to guess what the original password is by looking in dictionaries of MD5 hashes of many known words, these dictionaries can be useful to tell a user that the password that he has chosen may be easily discovered thus we can ask the user to build a more strong password.
Examples to Decrypt MD5 Password
Example 1:
Output:
In the above example, we print the hash value of “ PHP with Edureka” generated by the md5() function.
Example 2:
Output:
In the above example, we check if the hash value of variable $string is equal to 9a1359e7be2d2670780b85471675dc72 the program prints out “PHP with Edureka is Fun” else it prints “look for the error”
Example 3
Output:
In the above example, we look at the application of the raw parameter in the md5() function. If we set it to TRUE it gives a 16 character binary output else it simply gives 32 characters hex number.
Example 4:
Output:
The above code gives an output of an HTML form with a text block and a submit button if we enter the correct password it prints “Correct password” else it prints “Incorrect password”.
When we type in the wrong password for example here it checks for the hash of “pass” input with the hash of “pass123” the correct password if it does not match it gives out as follows
It prints out “Incorrect password”
If we type in the right password (i.e “pass123”) the hash of the input matches with the hash of the correct password and it gives the following output
It prints out “Correct password”
Now with this, we have come to the end of this article. I hope you guys enjoyed this article and understood the concepts of decryption. So, with the end of this PHP Tutorial, you are no longer a newbie to the scripting language.
If you wish to check out more articles on the market’s most trending technologies like Artificial Intelligence, Python, Ethical Hacking, then you can refer to Edureka’s official site.
Do look out for other articles in this series which will explain the various other aspects of PHP.
How can I decrypt a password hash in PHP?
I need to decrypt a password. The password is encrypted with password_hash function.
Now, let’s assume that $crypted is stored in a database (there’s a «users» table, with usernames, passwords, etc) and I need to do a login: I have to see if the password entered by the user matches the encrypted password stored in the database.
This is the sql code.
. but $inputpassword is not encrypted, so it’s not equal to what is stored in the password field of the table users.
So, there’s a function to decrypt after the use of password_hash ? Or should I change my encrypt method? Or what else?
5 Answers 5
Bcrypt is a one-way hashing algorithm, you can’t decrypt hashes. Use password_verify to check whether a password matches the stored hash:
In your case, run the SQL query using only the username:
And do the password validation in PHP using a code that is similar to the example above.
The way you are constructing the query is very dangerous. If you don’t parameterize the input properly, the code will be vulnerable to SQL injection attacks. See this Stack Overflow answer on how to prevent SQL injection.
The passwords cannot be decrypted as will makes a vulnerability for users. So, you can simply use password_verify() method to compare the passwords.
where, $upass is password entered by user and $userRow[‘user_pass’] is user_pass field in database which is encrypted by password_hash() function.
I need to decrypt a password. The password is crypted with password_hash function.
Its not clear to me if you need password_verify , or you are trying to gain unauthorized access to the application or database. Other have talked about password_verify , so here’s how you could gain unauthorized access. Its what bad guys often do when they try to gain access to a system.
First, create a list of plain text passwords. A plain text list can be found in a number of places due to the massive data breaches from companies like Adobe. Sort the list and then take the top 10,000 or 100,000 or so.
Second, create a list of digested passwords. Simply encrypt or hash the password. Based on your code above, it does not look like a salt is being used (or its a fixed salt). This makes the attack very easy.
Third, for each digested password in the list, perform a select in an attempt to find a user who is using the password:
So, rather than picking a user and trying to reverse their password, the bad guy picks a common password and tries to find a user who is using it. Odds are on the bad guy’s side.
Because the bad guy does these things, it would behove you to not let users choose common passwords. In this case, take a look at ProCheck, EnFilter or Hyppocrates (et al). They are filtering libraries that reject bad passwords. ProCheck achieves very high compression, and can digest multi-million word password lists into a 30KB data file.