Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何解密bcrypt存储的哈希_Perl_Bcrypt - Fatal编程技术网

Perl 如何解密bcrypt存储的哈希

Perl 如何解密bcrypt存储的哈希,perl,bcrypt,Perl,Bcrypt,我有一个加密密码的脚本,但我不知道如何将其反转和解密。这可能是一个非常简单的答案,但我不明白怎么做 #!/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 pas

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

#!/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));
}
你在散列,不是加密! 有什么区别?

区别在于散列是单向函数,而加密是双向函数

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

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

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

你现在所做的--散列密码--是正确的。如果您只是对密码进行加密,那么违反应用程序的安全性可能会允许恶意用户轻松地了解所有用户密码。如果您散列(或更好的)密码,用户需要破解密码(在
bcrypt
上这在计算上很昂贵)才能获得这些知识


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

您根本无法使用密码

bcrypt
使用盐渍,在不同的回合中,我通常使用10次

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

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

要回答原始问题。。。。要“解密”密码,你必须做密码破解者会做的事情

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

Bcrypt
增加了一个缓慢散列的安全特性。如果您的密码是用md5(糟糕的选择)散列的,那么您每秒可以检查数十亿个密码,但由于它是用
bcrypt
散列的,因此您每秒可以检查的密码要少得多


事实上,
bcrypt
散列和腌制的速度很慢,即使在今天,它仍然是密码存储的好选择。话虽如此,我相信NIST建议使用PBKDF2进行密码哈希。

您不能解密,但可以强制执行…

# Maybe you search this ??
For example in my case I use Symfony 4.4 (PHP).
If you want to update User, you need to insert the User password 
encrypted and test with the current Password not encrypted to verify 
if it's the same User. 

For example :

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 don'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 it's not verify', null);
         }

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

      }

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


来自github的脚本:

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

password\u验证(字符串$password,字符串$hash):bool


更多细节:

这正是散列的含义。你永远不能读取密码。你不能“解密”散列,因为它没有加密。哈希就像汉堡包。易于食用的牛->汉堡包。但是你想要汉堡包->牛。祝你好运…哦,好的,我明白了,谢谢!对不起,我弄糊涂了。@MarcB喜欢这个类比,以后会使用它。使用Authen::Passphrase,而不是拼凑自己的身份验证方案。查看“如何检查”中的“我的代码”,然后检查输入的密码是否与存储在数据库中的密码相同?@BluGeni
bcrypt
将多个密码映射为一个,因此如果用户插入密码,只需通过存储密码时使用的相同功能运行它(
加密密码($input)
)。如果输出相同,则用户插入了相同的密码。在这种情况下,我是否需要将salt保存在数据库中?这难道不违背吃盐的目的吗?因为现在我每次运行脚本$bigtest encrypted都是不同的,因为我相信是随机的salt?@BluGeni是的,你需要将salt保存在数据库中,不,这并没有破坏salt的目的。每个密码的salt都不同。这防止黑客获得(或生成)每1-8位密码的校验和表,并从一次操作中学习40%的用户登录。因此,亲爱的过去(6年前)的人们,上述信息是否仍然是处理存储在数据库中的密码的好方法?这个终于破解了吗?我这样问是因为我的一个用户的数据泄露了他们的“bcrypted”密码。这是否意味着窃贼现在拥有了密码?假设他们很可能无法破解加密的密码,这是否仍然安全?我确实理解,从理论上讲,用户需要继续更改任何被破坏的密码,但我是在询问用户是否没有更改密码。谢谢回答问题时,谈论代码的作用很重要。只有代码的答案可能很难理解。