54

我有这个加密密码的脚本,但我不知道如何反转和解密它。这可能是一个非常简单的答案,但我不明白该怎么做。

#!/usr/bin/perl
use Crypt::Eksblowfish::Bcrypt;
use Crypt::Random;

$password = 'bigtest';
$encrypted = encrypt_password($password);
print "$password is encrypted as $encrypted\n";

print "Yes the password is $password\n" if check_password($password, $encrypted);
print "No the password is not smalltest\n" if !check_password('smalltest', $encrypted);

# Encrypt a password 
sub encrypt_password {
    my $password = shift;

    # Generate a salt if one is not passed
    my $salt = shift || salt(); 

    # Set the cost to 8 and append a NUL
    my $settings = '$2a$08$'.$salt;

    # Encrypt it
    return Crypt::Eksblowfish::Bcrypt::bcrypt($password, $settings);
}

# Check if the passwords match
sub check_password {
    my ($plain_password, $hashed_password) = @_;

    # Regex to extract the salt
    if ($hashed_password =~ m!^\$2a\$\d{2}\$([A-Za-z0-9+\\.]{22})!) {
        return encrypt_password($plain_password, $1) eq $hashed_password;
    } else {
        return 0;
    }
}

# Return a random salt
sub salt {
    return Crypt::Eksblowfish::Bcrypt::en_base64(Crypt::Random::makerandom_octet(Length=>16));
}
4

6 回答 6

180

你在散列,而不是加密!

有什么不同?

不同之处在于散列是单向函数,而加密是双向函数。

那么,如何确定密码正确呢?

因此,当用户提交密码时,您不会解密存储的哈希值,而是bcrypt对用户输入执行相同的操作并比较哈希值。如果它们相同,则您接受身份验证。

您应该散列或加密密码吗?

你现在所做的——对密码进行哈希处理——是正确的。如果您只是简单地对密码进行加密,那么违反应用程序的安全性可能会使恶意用户轻松获悉所有用户密码。如果您散列(或者更好的是salt 和 hash)密码,用户需要破解密码(在 上计算成本很高bcrypt)才能获得该知识。

由于您的用户可能在多个地方使用他们的密码,这将有助于保护他们。

于 2013-08-06T15:44:12.387 回答
3

要回答原始发帖人的问题....要“解密”密码,您必须执行密码破解者会做的事情。

换句话说,您将运行一个程序来读取大量潜在密码(密码字典),然后使用bcrypt您尝试破译的密码中的盐分和复杂性对每个密码进行哈希处理。如果你很幸运,你会找到匹配的,但如果密码是强密码,那么你很可能找不到匹配的。

Bcrypt具有作为慢散列的附加安全特性。如果您的密码已使用 md5(糟糕的选择)进行哈希处理,那么您每秒可以检查数十亿个密码,但由于使用它进行哈希处理,bcrypt您每秒检查的密码会少得多。

即使在今天,散列和加盐的速度也bcrypt很慢,这使得它成为密码存储的好选择。话虽如此,我相信NIST推荐使用PBKDF2进行密码散列。

于 2020-03-04T17:43:36.510 回答
2

你根本做不到

bcrypt使用不同轮次的盐腌,我通常使用 10 次。

bcrypt.hash(req.body.password,10,function(error,response){ }

这 10 正在将随机字符串添加到您的密码中。

于 2020-01-10T14:18:37.880 回答
0

你不能解密,但你可以BRUTEFORCE它......

IE:迭代密码列表并检查其中一个是否与存储的哈希匹配。

来自 github 的脚本:https ://github.com/BREAKTEAM/Debcrypt

于 2020-11-17T12:54:20.180 回答
-1

也许你搜索这个?例如,在我的例子中,我使用 Symfony 4.4 (PHP)。如果要更新用户,则需要插入已加密的用户密码并使用未加密的当前密码进行测试,以验证是否为同一用户。

例如 :

public function updateUser(Request $req)
      {
         $entityManager = $this->getDoctrine()->getManager();
         $repository = $entityManager->getRepository(User::class);
         $user = $repository->find($req->get(id)); // get User from your DB

         if($user == null){
            throw  $this->createNotFoundException('User doesn\'t exist!!', $user);
         }
         $password_old_encrypted = $user->getPassword();//in your DB is always encrypted.
         $passwordToUpdate = $req->get('password'); // not encrypted yet from request.

         $passwordToUpdateEncrypted = password_hash($passwordToUpdate , PASSWORD_DEFAULT);

         // VERIFY IF IT'S THE SAME PASSWORD
         $isPass = password_verify($passwordToUpdateEncrypted , $password_old_encrypted );

         if($isPass === false){ // failure
            throw  $this->createNotFoundException('Your password is not valid', null);
         }

        return $isPass; // true!! it's the same password !!!
    
      }

于 2020-04-30T14:29:08.597 回答
-1

您可以在 PHP 中使用 password_verify 函数。它验证密码与哈希匹配

password_verify ( string $password , string $hash ) : bool

更多详情:https ://www.php.net/manual/en/function.password-verify.php

于 2020-12-20T08:12:33.110 回答