26

I need to decrypt a password. The password is encrypted with password_hash function.

$password = 'examplepassword';
$crypted = password_hash($password, PASSWORD_DEFAULT);

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...

$sql_script = 'select * from USERS where username="'.$username.'" and password="'.$inputpassword.'"';

...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?

11
  • 6
    password_verify() « Commented Jun 3, 2014 at 20:52
  • 13
    You can't decrypt it. A hash is a one-way function. Hash the password the user has given you and see the the hashes match. Commented Jun 3, 2014 at 20:52
  • 1
    you still can not. multiple inputs match the same hash Commented Jun 3, 2014 at 20:54
  • 15
    hashes are meat grinders. cow -> meat. You cannot go meat->cow. Commented Jun 3, 2014 at 20:56
  • 1
    Obligatory Security.SE Link: security.stackexchange.com/questions/211/… Commented Jun 3, 2014 at 20:57

4 Answers 4

41

Bcrypt is a one-way hashing algorithm, you can't decrypt hashes. Use password_verify to check whether a password matches the stored hash:

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

In your case, run the SQL query using only the username:

$sql_script = 'SELECT * FROM USERS WHERE 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.

Sign up to request clarification or add additional context in comments.

4 Comments

@user2864740 Added a note to my answer. I can't suggest a better query because I don't know if OP uses mysqli, PDO or some kind of ORM.
Thanks for adding the note (and the link is good) - I always recommend placeholders, but that's for a different question :|
Still, given how much code is just copy-pasted without much consideration that warning is far to tiny.
Where you assume you get into serious trouble. That should be username=? for the sake of sanity.
5

The passwords cannot be decrypted as will makes a vulnerability for users. So, you can simply use password_verify() method to compare the passwords.

if(password_verify($upass, $userRow['user_pass'])){
     //code for redirecting to login screen }

where, $upass is password entered by user and $userRow['user_pass'] is user_pass field in database which is encrypted by password_hash() function.

Comments

1

I need to decrypt a password. The password is crypted with password_hash function.

$password = 'examplepassword';
$crypted = password_hash($password, PASSWORD_DEFAULT);

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:

$sql_script = 'select * from USERS where password="'.$digested_password.'"'

Fourth, profit.

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.

2 Comments

I don't think the OP was trying to hack anything, and besides, you have to have admin powers on the server you're trying to brute force.
@LeoWilson - He wants to recover the password. Being an admin is not enough to do it since the password is hashed.
1

Use the password_verify() function

if (password_vertify($inputpassword, $row['password'])) {
  print "Logged in";
else {
    print "Password Incorrect";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.