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操作を実行してハッシュを比較します。それらが同一である場合、認証を受け入れます。

パスワードをハッシュまたは暗号化する必要がありますか?

あなたが今やっていること -- パスワードのハッシュ -- は正しいです。単純にパスワードを暗号化すると、アプリケーションのセキュリティが侵害され、悪意のあるユーザーがすべてのユーザー パスワードを簡単に知ることができる可能性があります。パスワードをハッシュ化 (またはソルト アンド ハッシュ化bcrypt) した場合、ユーザーはその知識を得るためにパスワードをクラックする必要があります (これは で計算コストが高くなります)。

ユーザーはおそらく複数の場所でパスワードを使用するため、これはユーザーを保護するのに役立ちます。

于 2013-08-06T15:44:12.387 に答える
-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 に答える