6

私は自分のアプリケーションの認証コンポーネントに取り組んでいます。塩味のパスワードでApacheShiroAPIを使用しています。

この例のように、saltを使用して新しいユーザーを作成します。

ByteSource salt = randomNumberGenerator.nextBytes(32);      
byte[] byteTabSalt = salt.getBytes();   
String strSalt = byteArrayToHexString(byteTabSalt);         
String hashedPasswordBase64 = new Sha256Hash(inPassword, salt, 512).toBase64();

しかし、doGetAuthenticationInfoメソッドでユーザーをautenticateするためにsaltをどのように使用するのか理解できません。私のメソッドはSaltedAuthenticatedInfoを返す必要がありますが、それをどのように作成するのかわかりません。

資格情報マッチャーとSaltedAuthenticateInfoの間のリンクがわかりません。

パスワードソルトを作成するときに、クレデンシャルマッチャーに通知する必要がありますか?

ご協力いただきありがとうございます。

4

2 に答える 2

7

SaltedAuthenticationInfo

SaltedAuthenticationInfoインターフェースです。Shiro APIは、便宜上、いくつかのデフォルトの実装を提供します。可能な限り、デフォルトの実装の1つを使用してみてください。独自に作成することは避けてください。
どちらSimpleAuthenticationInfoが実装するかだけSaltedAuthenticationInfoではありませんが、おそらくあなたの目的には十分でしょう。
詳細については、 org.apache.shiro.authc.SimpleAuthenticationInfoを参照してください。

どうしても独自に実装する必要がある場合SaltedAuthenticationInfoは、ドキュメントに注意深く従う必要があります。
詳細については、 org.apache.shiro.authc.AuthenticationInfoおよびorg.apache.shiro.authc.SaltedAuthenticationInfoを参照してください。

HashedCredentialMatcher

boolean doCredentialsMatch(AuthenticationToken, AuthenticationInfo)実際に認証ロジックを処理します。
このメソッドは、の形式でユーザーが送信した資格情報を取得しAuthenticationToken、以前に保存されたの形式の資格情報と比較しますAuthenticationInfo。ただし、最初に必要なすべての情報(反復、アルゴリズム、およびのソルト)
を渡すようにする必要があります。 HashCredentialMatcherSaltedAuthenticationInfo

疑似例の使用、

final int iterations = 50000;

AuthenticationToken authToken = ...;
SaltedAuthenticationInfo saltedAuthInfo = ...;

HashedCredentialsMatcher authenticator = 
     new HashedCredentialsMatcher(Sha256Hash.ALGORITHM_NAME);
authenticator.setHashIterations(iterations);

final boolean successfulAuthentication = 
     authenticator.doCredentialsMatch(authToken, saltedAuthInfo);

詳細については、 org.apache.shiro.authc.credential.HashedCredentialsMatcherを参照してください。

その他のセキュリティ上の注意

  • 塩の長さ
    256ビットの塩はよさそうだ。その大きさのソルトを使用すると、2人のユーザーが同じソルトを共有するリスクを最小限に抑えることができます。誕生日のパラドックスが作用する塩の長さを選ぶときは覚えておいてください。

  • 反復回数
    経験則として、10,000未満を使用しないでください。現在512を使用しています。

    String hashedPasswordBase64 = new Sha256Hash(inPassword, salt, 512).toBase64();
    

    ほとんどのハッシュアルゴリズムは非常に高速であり(sha256を含む)、ハッカーになる可能性のある人には何の恩恵も与えたくありません。使用する反復回数が多いほど認証は遅くなりますが、クラッキングの試行も直接遅くなります。

    アプリケーションの許容可能な応答性を維持しながら、反復回数を可能な限り高く設定する必要があります。あなたはあなたがどれほど高く行くことができるかに驚くかもしれません。
    個人的に私は数百万を使用する傾向があります。しかし、私は妄想的で、少し遅れてもかまいません。詳細については、キーストレッチ
    を 参照してください。

  • 個人的には、ハッシュパラメータ(ハッシュアルゴリズム、ソルトサイズ、反復回数など)をハードコーディングすることは避けます
    。これらの値をハードコーディングすると、すぐに適応して応答する能力が制限されます。

    これらの値をハッシュされたクレデンシャルとともに保存すると、より動的な認証を行うことができ、比較的少ない労力で将来、より強力なアルゴリズムを構成および展開できます。

    たとえば、デフォルトのハッシュアルゴリズムは、50,000回の反復と256ビットのソルトを使用するsha256の場合があります。将来的には、50,000回の反復では不十分になる可能性があります。
    大騒ぎせずに、優先アルゴリズム構成を変更して、すべての新しいパスワードに対して100,000回繰り返すことができます。既存のクレデンシャルで保存したアルゴリズムパラメータを変更しないため、古いパスワードを壊すことを心配する必要はありません。これを使用して、ソルトサイズまたはアルゴリズム全体を変更することもできます。

    必要に応じて、全員にパスワードを変更させることができます。ユーザーに新しい(できればより強力な)優先アルゴリズムのセットアップを選択させる。
    Unixオペレーティングシステムは、これを何年もの間/ etc/shadowで行ってきました。

    前もってもう少し手間がかかりますが、投資する価値があります。強力な認証制御が重要です。

于 2012-09-11T17:42:14.857 に答える
0

私のエラーは、AuthenticationTokenを比較するAuthenticationInfoを正しく作成しなかったことです。したがって、自分のレルムのdoGetAuthenticationInfoメソッドでこれを行います。

Object principal   = arg0.getPrincipal();
Object credentials = arg0.getCredentials();
String realmName   = this.getName(); // to get the realm name

SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal, credentials, realmName);

CredentialsMatcher credentialsMatcher = this.getCredentialsMatcher();
boolean successfulAuthentication = credentialsMatcher.doCredentialsMatch(arg0, simpleAuthenticationInfo);

したがって、ブール値のsuccessfulAuthenticationはtrueです。しかし、CredentialsMatcherとHashedCredentialsMatcherの違いは何であるかわかりません。なぜなら、それは誤りだったからです。Javadocを読まなければなりません。

于 2012-09-12T11:49:23.080 に答える