web-dev-qa-db-ja.com

Spring BCryptPasswordEncoderは同じ入力に対して異なるパスワードを生成します

私はSpringセキュリティでBCryptPasswordEncoderを使用しています。しかし問題は、同じ入力に対して異なるエンコードされたパスワードを生成することです。

    String password = "123456"; 
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
    String encodedPassword = passwordEncoder.encode(password);  
    System.out.print(encodedPassword);


output : $2a$10$cYLM.qoXpeAzcZhJ3oXRLu9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi

output2 : $2a$10$KEvYX9yjj0f1X3Wl8S.KPuWzSWGyGM9ubI71NOm3ZNbJcwWN6agvW

output3 : $2a$10$nCmrPtUaOLn5EI73VZ4Ouu1TmkSWDUxxD4N6A.8hPBWg43Vl.RLDC

そのたびに異なる出力を生成します。

18
Bhavesh
public static void main(String[] args) {
  // spring 4.0.0
  org.springframework.security.crypto.password.PasswordEncoder encoder
   = new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder();

   // $2a$10$lB6/PKg2/JC4XgdMDXyjs.dLC9jFNAuuNbFkL9udcXe/EBjxSyqxW
   // true
   // $2a$10$KbQiHKTa1WIsQFTQWQKCiujoTJJB7MCMSaSgG/imVkKRicMPwgN5i
   // true
   // $2a$10$5WfW4uxVb4SIdzcTJI9U7eU4ZwaocrvP.2CKkWJkBDKz1dmCh50J2
   // true
   // $2a$10$0wR/6uaPxU7kGyUIsx/JS.krbAA9429fwsuCyTlEFJG54HgdR10nK
   // true
   // $2a$10$gfmnyiTlf8MDmwG7oqKJG.W8rrag8jt6dNW.31ukgr0.quwGujUuO
   // true

    for (int i = 0; i < 5; i++) {
      // "123456" - plain text - user input from user interface
      String passwd = encoder.encode("123456");

      // passwd - password from database
      System.out.println(passwd); // print hash

      // true for all 5 iteration
      System.out.println(encoder.matches("123456", passwd));
    }
}
25
blueberry0xff

生成されたパスワードはソルト化されているため、異なります。

encode() メソッドのドキュメントを読んで、パスワードがソルトされていることを明記してください。

15
Uwe Plonus

BCryptPasswordEncoder はソルトを使用してパスワードを生成するため、これはまったく正常です。パスワードの「塩漬け」の背後にある考え方について読むことができます here および here

これはencodeメソッドに関するドキュメントの記述です

生のパスワードをエンコードします。一般的に、適切なエンコードアルゴリズムは、8バイト以上のランダムに生成されたソルトと組み合わせたSHA-1以上のハッシュを適用します。

5
geoand

2番目の$の直後の22文字はソルト値を表します。 https://en.wikipedia.org/wiki/Bcrypt#Description を参照してください。 「塩」は、ハッシュする前にパスワードに追加されるランダムデータです。したがって、ほとんどの場合、特定のパラメーターを持つ特定のハッシュアルゴリズムは、同じパスワードに対して異なるハッシュ値を生成します(いわゆるレインボー攻撃に対する保護)。

元の質問に示されている最初の出力を分析してみましょう:$2a$10$cYLM.qoXpeAzcZhJ3oXRLu9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi

  • $2a:BCryptアルゴリズムの識別子
  • $10:ラウンド数のパラメーター、ここでは2 ^ 10ラウンド
  • cYLM.qoXpeAzcZhJ3oXRLu:ソルト(128ビット)
  • 9Slkb61LHyWW5qJ4QKvHEMhaxZ5qCPi:実際のハッシュ値(184ビット)

ソルト値とハッシュ値は両方ともRadix-64を使用してエンコードされます。

3
user1364368