如何在 PHP 中解密密码哈希?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24024702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 17:07:00  来源:igfitidea点击:

How can I decrypt a password hash in PHP?

phpmysqlencryption

提问by dariodp

I need to decrypt a password. The password is encrypted with password_hashfunction.

我需要解密密码。密码是用password_hash函数加密的。

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

Now, let's assume that $cryptedis 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.

现在,让我们假设它$crypted存储在数据库中(有一个“用户”表,包含用户名、密码等),我需要登录:我必须查看用户输入的密码是否与存储在的加密密码匹配数据库。

This is the sql code...

这是sql代码...

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

...but $inputpasswordis not encrypted, so it's not equal to what is stored in the password field of the table users...

...但$inputpassword没有加密,所以它不等于表用户的密码字段中存储的内容...

So, there's a function to decrypt after the use of password_hash? Or should I change my encrypt method? Or what else?

那么,有一个函数可以在使用后解密password_hash?或者我应该改变我的加密方法?或者还有什么?

回答by Gergo Erdosi

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

Bcrypt 是一种单向散列算法,您无法解密散列。使用password_verify检查密码是否与存储的哈希匹配:

<?php
// See the password_hash() example to see where this came from.
$hash = 'y$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 查询:

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

And do the password validation in PHP using a code that is similar to the example above.

并使用与上述示例类似的代码在 PHP 中进行密码验证。

Edit: Constructing the query this way is very dangerous. If you don't escape the input properly, the code will be vulnerable to SQL injection attacks. See thisSO answer on how to prevent SQL injection.

编辑:以这种方式构建查询非常危险。如果您没有正确转义输入,代码将容易受到 SQL 注入攻击。见对如何防止SQL注入SO答案。

回答by jww

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

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

我需要解密密码。密码使用 password_hash 函数加密。

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

我不清楚您是否需要password_verify,或者您正试图获得对应用程序或数据库的未经授权的访问。其他人已经谈到password_verify,所以这里是您如何获得未经授权的访问。这是坏人在尝试访问系统时经常做的事情。

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.

首先,创建一个纯文本密码列表。由于 Adob​​e 等公司的大量数据泄露,可以在许多地方找到纯文本列表。对列表进行排序,然后取前 10,000 或 100,000 左右。

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

因为坏人做这些事,就对...是应该的你不是让用户选择常用的密码。在这种情况下,请查看 ProCheck、EnFilter 或 Hyppocrates(等)。他们正在过滤拒绝错误密码的库。ProCheck 实现了非常高的压缩率,可以将数百万字的密码列表消化成 30KB 的数据文件。

回答by Cholis

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

似乎有人终于创建了一个脚本来解密 password_hash。结帐这个: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 = 'y$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";
}
?>

回答by Cholis

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

密码无法解密,因为这会给用户带来漏洞。因此,您可以简单地使用password_verify()方法来比较密码。

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

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

其中,$upass是用户输入的密码,$userRow['user_pass']是数据库中被password_hash()函数加密的user_pass字段。

回答by nullminer

Use the password_verify() function

使用 password_verify() 函数

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