1. ホーム
  2. perl

[解決済み] bcryptで保存したハッシュを復号化する方法

2022-03-02 23:48:51

質問

パスワードを暗号化するスクリプトがあるのですが、それを逆にして復号化する方法がわかりません。これは非常に簡単な答えかもしれませんが、私はそれを行う方法を理解していない。

#!/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 )を得ることができます。

ユーザーはパスワードを複数の場所で使用していると思うので、パスワードの保護に役立ちます。