perl 如何解密bcrypt存储的hash

bgtovc5b  于 2023-10-24  发布在  Perl
关注(0)|答案(6)|浏览(213)

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

#!/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));
}
x9ybnkn6

x9ybnkn61#

你是在散列,不是在拥抱!

有什么区别

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

那么,如何确定密码是否正确?

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

你应该散列或加密密码?

您现在所做的--对密码进行散列--是正确的。如果您只是对密码进行加密,那么应用程序的安全漏洞可能会让恶意用户轻松地了解所有用户的密码。如果您对密码进行散列(或者更好的salt and hash),则用户需要破解密码(在bcrypt上计算成本很高)才能获得这些信息。
由于您的用户可能在多个地方使用密码,这将有助于保护他们。

bttbmeg0

bttbmeg02#

要回答原始海报的问题.解密密码,你必须做什么密码破解会做。
换句话说,你需要运行一个程序来读取一个大的潜在密码列表(一个密码字典),然后使用bcrypt以及你试图破译的密码的盐值和复杂度来对每个密码进行哈希。如果你幸运的话,你会找到一个匹配的密码,但是如果密码是一个强密码,那么你很可能找不到匹配的密码。
Bcrypt具有作为慢散列的额外安全特性。如果您的密码使用md5散列(糟糕的选择),那么您可以每秒检查数十亿个密码,但由于它使用bcrypt散列,因此您每秒可以检查的密码要少得多。
事实上,bcrypt的哈希和salted速度很慢,这使得它即使在今天也是密码存储的好选择。话虽如此,我相信NIST推荐使用PBKDF 2进行密码哈希。

w8rqjzmb

w8rqjzmb3#

你就是不能

bcrypt使用盐腌,不同的回合,我通常使用10个。

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

这10是随机字符串到你的密码。

gk7wooem

gk7wooem4#

也许你搜索这个?例如,在我的情况下,我使用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 !!!
    
      }
laawzig2

laawzig25#

您可以在PHP中使用password_verify函数。它验证密码是否与哈希值匹配
password_verify ( string $password , string $hash ) : bool
更多详情:https://www.php.net/manual/en/function.password-verify.php

uxhixvfz

uxhixvfz6#

import (
    "fmt"
    "golang.org/x/crypto/bcrypt"
)

// Save password in hash
func HashPassword(password string) (string, error) {
    bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
    return string(bytes), err
}

// check password in hash
func CheckPasswordHash(password, hash string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
    return err == nil
}

func main() {
    password := "password"
    hash, _ := HashPassword(password) // ignore error for the sake of simplicity

    fmt.Println("Password:", password)
    fmt.Println("Hash:    ", hash)

    match := CheckPasswordHash(password, hash)
    fmt.Println("Password match or not:", match) // It will return true or false
}

相关问题