简体   繁体   English

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

[英]How can I decrypt a password hash in PHP?

I need to decrypt a password.我需要解密密码。 The password is encrypted with password_hash function.密码使用password_hash函数加密。

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

This is the sql code...这是sql代码...

$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... ...但是$inputpassword没有加密,所以它不等于表 users 的密码字段中存储的内容...

So, there's a function to decrypt after the use of password_hash ?那么,在使用password_hash后有一个解密函数吗? Or should I change my encrypt method?或者我应该改变我的加密方法? Or what else?或者还有什么?

Bcrypt is a one-way hashing algorithm, you can't decrypt hashes. Bcrypt 是一种单向散列算法,您无法解密散列。 Use password_verify to check whether a password matches the stored hash:使用password_verify检查密码是否与存储的哈希匹配:

<?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 查询:

$sql_script = 'SELECT * FROM USERS WHERE username=?';

And do the password validation in PHP using a code that is similar to the example above.并使用与上述示例类似的代码在 PHP 中进行密码验证。

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.如果您没有正确地参数化输入,代码将容易受到 SQL 注入攻击。 See this Stack Overflow answer on how to prevent SQL injection.请参阅有关如何防止 SQL 注入的堆栈溢出答案

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, $upass is 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']是数据库中的 user_pass 字段,由password_hash()函数加密。

I need to decrypt a password.我需要解密密码。 The password is crypted with password_hash function.密码使用 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.我不清楚您是否需要password_verify ,或者您试图获得对应用程序或数据库的未经授权的访问。 Other have talked about password_verify , so here's how you could gain unauthorized access.其他人谈到了password_verify ,所以这里是您如何获得未经授权的访问。 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.由于 Adob​​e 等公司的大量数据泄露,可以在许多地方找到纯文本列表。 Sort the list and then take the top 10,000 or 100,000 or so.对列表进行排序,然后取前 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 not let users choose common passwords.因为坏人做这些事,就对...是应该的,你不能让用户选择常用的密码。 In this case, take a look at ProCheck, EnFilter or Hyppocrates (et al).在这种情况下,请查看 ProCheck、EnFilter 或 Hyppocrates(等)。 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 实现了非常高的压缩率,可以将数百万字的密码列表消化成 30KB 的数据文件。

Use the password_verify() function使用 password_verify() 函数

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

it seems someone finally has created a script to decrypt password_hash.似乎有人终于创建了一个脚本来解密 password_hash。 checkout this one: https://pastebin.com/Sn19ShVX结帐这个: 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";
}
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM