2016-08-24 52 views
1

私のアプリケーションには春のセキュリティが使用されています。ユーザーが初めて登録すると、パスワードはBCryptPasswordEncoderで暗号化されます。BCryptPasswordEncoderから元のパスワードを取得する方法

BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
String hashedPassword = passwordEncoder.encode(password); 

さて、パスワードの変更の場合には、ユーザーが自分の現在のパスワードを入力し、私は、この現在のパスワードがデータベースに保存されている暗号化されたパスワードに対して同じであるかどうかを確認する必要があります。

BCryptPasswordEncoderと同じ文字列を持つ同じ暗号化されたハッシュを生成することはできません。したがって、パスワードが同じであればパスワードを比較する唯一の方法は、データベースに保存されている元のパスワードを取得し、現在入力されているパスワードと比較することです。

パスワードを比較したり、元のパスワードをデータベースの保存されたハッシュパスワードから取得する方法はありますか?

答えて

3

db内のエンコードされたパスワードに対して未処理のパスワードのみをチェックする必要があります。例えば、

BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); 
String p = bCryptPasswordEncoder.encode("SomeCoolPassword"); 
System.out.println(bCryptPasswordEncoder.matches("SomeCoolPassword", p)); 
+0

素晴らしい解決策ですが、私の場合は本当に遅いです。このようなパスワード検証方法(anywhery、dorin 'login'など)を使用すると、実行時間(プロファイラでテスト済み)の84%(!!!)を要し、何らかの方法で実装する必要があります。そのチェックが最適化されていないように見えます) –

+0

@AlexEfimov、私は実際の時間とconfigsを見るのは興味深いでしょう。その理由は、比較的重要でない時間の84%も重要ではありません。この特定のタスクは遅いですが、パフォーマンスとセキュリティは相反する力/要件であり、特定の要件は面倒なトレードオフを要求する可能性があります。私はログインのためにいくつかのWebアプリケーションでこの正確なコードを使用し、それに問題はなかった。 [また、いくつかの情報についてこの受け入れられた答えを見てください](https://security.stackexchange.com/questions/17207/recommended-of-rounds-for-bcrypt)。 – ChiefTwoPencils

2

はい、passwordEncoderは同じハッシュを作成しませんが、あなたはそれらを比較することができ、そしてそれは、同じ文字列から生成された場合、それはtrueを返します。私の例を確認してください:

public class Test { 
    public static void main(String[] args) { 
     BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); 
     List<String> passwords = Arrays.asList(bCryptPasswordEncoder.encode("testPassword"), 
       bCryptPasswordEncoder.encode("testPassword"), 
       bCryptPasswordEncoder.encode("testPassword"), 
       bCryptPasswordEncoder.encode("testPassword")); 

     passwords.stream() 
       .filter(e -> bCryptPasswordEncoder.matches("testPassword", e)) 
       .forEach(e -> System.out.println(true)); 
    } 

}

と私は4 trueを取得します。

関連する問題