web-dev-qa-db-ja.com

Asp.net IDパスワードハッシュ

新しいASP.net Identityプロジェクトは、Webサイトのセキュリティに役立つコードとインターフェイスをもたらしました。 (MVC 5テンプレートに含まれる標準のEntity Framework実装を使用する代わりに)インターフェイスを使用してカスタムシステムを実装するには、IPasswordHasherが必要です。

ASP.net IdentityのIPasswordHasherインターフェイス

namespace Microsoft.AspNet.Identity
{
    public interface IPasswordHasher
    {
         string HashPassword(string password);
         PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword);
    }
}

ASP.net Identityで、このインターフェイスを介してより安全な暗号化のためにパスワードソルトを使用することは可能ですか?

33
Edward Wilson

「パスワードソルティングを使用して、ASP.net Identityで、このインターフェイスを介してより安全な暗号化を行うことはできますか?」

はい、Coreフレームワークにすでに存在するPasswordHasherの新しい実装用のインターフェイスが提供されています。

また、デフォルトの実装では既にSalt + Bytesを使用していることに注意してください。

カスタムPasswordHasher(たとえばMyPasswordHasher)を作成したら、userManager.PasswordHasher=new MyPasswordHasher()のようにUserManagerインスタンスに割り当てることができます

そのようなIPasswordHasherの1つの例を参照

(MVC 5テンプレートに含まれる標準のEntity Framework実装を使用する代わりに)インターフェイスを使用してカスタムシステムを実装するには、IPasswordHasherが必要です。

EFから代替システムを実装するには、すべてのコアインターフェイスを実装する必要があります。 -IPasswordHasherの実装は必要ありません。 PasswordHasherはコアフレームワークの実装として既に提供されています。

34
jd4u

以下の回答の健康警告:使用しているASP.Net Identityのバージョンを確認してください。 githubリポジトリの新しいバージョンの1つである場合は、ソースコードを直接参照する必要があります。

これを書いているとき、パスワードハンドラの現在のバージョン( .0.0-rc1 /.../ PasswordHasher.cs )は、以下の回答とは大きく異なります。この新しいバージョンは、複数のハッシュアルゴリズムバージョンをサポートし、文書化されています(これを読むまでにさらに変更される可能性があります)。

バージョン2:

  • HMAC-SHA1、128ビットソルト、256ビットサブキー、1000回の反復を伴うPBKDF2。
  • (参照:SDL暗号ガイドラインv5.1、パートIII)
  • フォーマット:_{ 0x00, salt, subkey }_

バージョン3:

  • HMAC-SHA256、128ビットソルト、256ビットサブキー、10000回の繰り返しを使用したPBKDF2。
  • 形式:{ 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
  • (すべてのUInt32はビッグエンディアンに格納されます。)

元の回答は、ASP.Net Identityの元のバージョンに対して有効であり、次のとおりです。


@ jd4uは正しいですが、彼の答えのコメントに収まらないもう少し光を当てるために:

したがって、_Rfc2898DeriveBytes_を使用する場合は、PasswordHasherを使用してください。すべての面倒な作業は既に(できれば正しく)行われています。

詳細

PasswordHasherが(現在)最終的に使用する完全なコードは、以下に非常に近いものを実行します。

_int saltSize = 16;
int bytesRequired = 32;
byte[] array = new byte[1 + saltSize + bytesRequired];
int iterations = SOME; // 1000, afaik, which is the min recommended for Rfc2898DeriveBytes
using (var pbkdf2 = new Rfc2898DeriveBytes(password, saltSize, iterations))
{
    byte[] salt = pbkdf2.Salt;        
    Buffer.BlockCopy(salt, 0, array, 1, saltSize);
    byte[] bytes = pbkdf2.GetBytes(bytesRequired);
    Buffer.BlockCopy(bytes, 0, array, saltSize+1, bytesRequired);
}
return Convert.ToBase64String(array);
_
57
Andy Brown

MembershipからAspNet.Identityに更新中に問題に遭遇しました。 Rfc2898ハッシュは以前に使用されたものとは異なります。これには十分な理由がありますが、ハッシュを変更するには、すべてのユーザーがパスワードをリセットする必要があります。ソリューションとして、このカスタム実装は後方互換性を持たせます:

public class MyPasswordHasher : PasswordHasher {

   public FormsAuthPasswordFormat FormsAuthPasswordFormat { get; set; }

   public MyPasswordHasher(FormsAuthPasswordFormat format) {
      FormsAuthPasswordFormat = format;
   }

   public override string HashPassword(string password) {
      return FormsAuthentication.HashPasswordForStoringInConfigFile(password, FormsAuthPasswordFormat.ToString());
   }

   public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) {
     var testHash = FormsAuthentication.HashPasswordForStoringInConfigFile(providedPassword, FormsAuthPasswordFormat.ToString());
     return hashedPassword.Equals(testHash) ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed;
   }
}

UserManagerインスタンスを作成したら、ハッシュを設定するだけです:

Usermanager.PasswordHasher = new MyPasswordHasher(FormsAuthPasswordFormat.SHA1);

このコードはHashPasswordForStoringInConfigFileメソッドが非推奨であると文句を言っていますが、これは問題なく実行できるのは古い技術を取り除くことだということです。

8
Joerg Krause