25

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?

Nik
  • 2,885
  • 2
  • 25
  • 25
dariodp
  • 423
  • 2
  • 5
  • 12

5 Answers5

37

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.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Gergo Erdosi
  • 40,904
  • 21
  • 118
  • 94
  • @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. – Gergo Erdosi Jun 03 '14 at 21:09
  • Thanks for adding the note (and the link is good) - I always recommend placeholders, but that's for a different question :| – user2864740 Jun 03 '14 at 21:10
  • 1
    Still, given how much code is just copy-pasted without much consideration that warning is far to tiny. – Perseids Jun 03 '14 at 21:11
  • 2
    Where you assume you get into serious trouble. That should be `username=?` for the sake of sanity. – tadman Jun 03 '14 at 21:27
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.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
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.

jww
  • 97,681
  • 90
  • 411
  • 885
  • 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. – Leo Wilson Feb 02 '17 at 03:47
  • @LeoWilson - He wants to recover the password. Being an admin is not enough to do it since the password is hashed. – jww Feb 02 '17 at 09:11
1

Use the password_verify() function

if (password_vertify($inputpassword, $row['password'])) {
  print "Logged in";
else {
    print "Password Incorrect";
}
nullminer
  • 19
  • 5
-2

it seems someone finally has created a script to decrypt password_hash. checkout this one: https://pastebin.com/Sn19ShVX

<?php
error_reporting(0);

# Coded by L0c4lh34rtz - IndoXploit

# \n -> linux
# \r\n -> windows
$list = explode("\n", file_get_contents($argv[1])); # change \n to \r\n if you're using windows
# ------------------- #

$hash = '$2y$10$BxO1iVD3HYjVO83NJ58VgeM4wNc7gd3gpggEV8OoHzB1dOCThBpb6'; # hash here, NB: use single quote (') , don't use double quote (")

if(isset($argv[1])) {
    foreach($list as $wordlist) {
        print " [+]"; print (password_verify($wordlist, $hash)) ? "$hash -> $wordlist (OK)\n" : "$hash -> $wordlist (SALAH)\n";
    }
} else {
    print "usage: php ".$argv[0]." wordlist.txt\n";
}
?>
Cholis
  • 25
  • 5
  • 2
    1. That is not decryption, it is a brute force attack. 2. Try it, time it on 100,000 `password_hash`'ed passwords. 3. This method is well known and the point of `password_hash` is to consume substantial CPU tine in order to make a brute force attack very time consuming. It is the best we can do. – zaph Sep 23 '17 at 21:43
  • yupp, nont decryptor. but it is not bruce force attack if they do in their own pc/server... it's depend on big collection (database, wordlist) of password, like they do with so much MD5 database. – Cholis Sep 24 '17 at 02:19
  • 1
    1. It is still a brute force attack, that is a method, it makes no difference who or where it is done. 2. it is not like an MD5 rainbow table attack because there is a random seed involved in `password_hash` so the `password_verification` calculation must be made for each password tried. 3. The cost should be chosen such that `password_verification` takes about 100ms, substantially slower than MD5 of a password that can usually be calculated in less than 0.01ms so `password_verification` is about 100,000 times slower than MD5 in the same class CPU that `password_hash` was calculated on. – zaph Sep 24 '17 at 09:36