2012-11-23 68 views
34

.Net 4.5にアップグレードした後、 "System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFileが廃止されました"という警告が表示されました。代わりに、メンバーシップAPIを使用することをお勧めします。FormsAuthentication.HashPasswordForStoringInConfigFileの代わりにドロップ?

これはすべて新しいプロジェクトではうってつけですが、この段階(ユーザーデータとハッシュパスワードが存在します)では、さまざまなハッシュ方法を持つカスタムメンバーシッププロバイダーに変更することはできません。

このような問題のために推奨される方法を教えてください。 "廃止された"呼び出しを引き続き使用することは、明らかに推奨されたパスではないので、「メンバーシップAPIを使用する」以外のものに置き換えられていますか?

+0

を使用することはできませんHashPasswordForStoringInConfigFileは古く、交換用の代替を提案するために誰かのために、彼らは第二のパラメータを知っている必要があり、それは「MD5」または「SHA1」となっていますか?はい、私はこの投稿が古いと知っていますが、何年も前に 'HashPasswordForStoringInConfigFile'を使用していなかったので、私はそれを見つけました。塩+パスワードのSHA1の置き換えはうまくいきますが、2016年のこの時点では、ひどいMD5はもちろんのこと、SHA1に固執するのは悪い考えです。 –

答えて

43

これはSHA1バリアントの解決策です。

だけにアルゴリズムを変更する必要がMD5の場合
 public static string GetSwcSHA1(string value) 
    { 
     SHA1 algorithm = SHA1.Create(); 
     byte[] data = algorithm.ComputeHash(Encoding.UTF8.GetBytes(value)); 
     string sh1 = ""; 
     for (int i = 0; i < data.Length; i++) 
     { 
      sh1 += data[i].ToString("x2").ToUpperInvariant(); 
     } 
     return sh1; 
    } 

MD5 algorithm = MD5.Create(); 

は直上あなたのコードのVB.NETバリアントを追加しようと、あなたが気にしないホープ

Public Shared Function CreateHash(saltAndPassword) As String 
     Dim Algorithm As SHA1 = SHA1.Create() 
     Dim Data As Byte() = Algorithm.ComputeHash(Encoding.UTF8.GetBytes(saltAndPassword)) 
     Dim Hashed As String = "" 

     For i As Integer = 0 To Data.Length - 1 
      Hashed &= Data(i).ToString("x2").ToUpperInvariant() 
     Next 

     Return Hashed 
    End Function 
+0

非常に参考になりました! VB.Netに関数宣言などを含めて更新しても大丈夫でしょうか? –

+0

GetSwcSH1のSwcはどういう意味ですか? – Wes

2

リチャードの答えは私のためにうまくいった。 これは.NET Framework 4.5からコンパイルされたコードです。 誰かがそれを使用する方がよい場合は、それを使用してください。私はそれが少し速いかもしれないと思う。

 public static string BinaryToHex(byte[] data) 
     { 
      if (data == null) 
      { 
       return null; 
      } 
      char[] hex = new char[checked((int)data.Length * 2)]; 
      for (int i = 0; i < (int)data.Length; i++) 
      { 
       byte num = data[i]; 
       hex[2 * i] = NibbleToHex((byte)(num >> 4)); 
       hex[2 * i + 1] = NibbleToHex((byte)(num & 15)); 
      } 
      return new string(hex); 
     } 

     private static char NibbleToHex(byte nibble) 
     { 
      int aChar = (nibble < 10 ? nibble + 48 : nibble - 10 + 65); 
      return (char)aChar; 
     } 
9

このような問題のために前方いただきまし推奨方法はありますか? "廃止された"呼び出しを引き続き使用することは、明らかに推奨されたパスではないので、「メンバーシップAPIを使用する」以外のものに置き換えられていますか?

純粋に.NET Framework内で最も良い方法は、PBKDF2、Bcrypt、またはScryptによってパスワードがハッシュされるようにすべてを変更することです。 PBKDF2は.NETでRfc2898DeriveBytes Classによって提供されています。

秒最良の方法は、パスワードの二つの「バージョン」で終わることです:

  • バージョン0は古いHashPasswordForStoringInConfigFileだったでしょうが、あなたは一括でそれらを更新することができ、オフライン、バージョン1および削除誰かがそれらを盗む前にそれらの古いハッシュは全体的にハッシュし、あなたは哀れな90年代のパスワードのハッシングを持つとして取引のニュースに終わります。
  • バージョン1は、既存のHashPasswordForStoringInConfigFile値のPBKDF2です!私。あなたは現在の厄介な古いハッシュを取り、PBKDF2に新しいランダムな塩と高い反復回数を付けて結果を保存します。ユーザーがログインしたい場合は、@RichardBažantが書いたコードにパスワードを入力して、HashPasswordForStoringInConfigFileが返すものを持っているので、を入力してを入力すると、その結果にPBKDF2が適用されます。
    • すなわち、それは)YourIterations、実際にはバージョン1つのハッシュがにアップグレードされているユーザー
  • バージョン2、PerUserSalt Rfc2898DeriveBytes(HashPasswordForStoringInConfigFile(パスワード))です。「バージョン」を除くすべての列は同じですが、バージョン1を計算して検証した後、Rfc2898DeriveBytes(パスワード)、PerUserSalt、YourIterationsを計算し、バージョン1のハッシュをバージョン2のハッシュに置き換えます(バージョンを2、もちろん)。

第三の最良の方法は、第二の最良の方法ですが、唯一のバージョンで1.注意してください、この方法はDCC2狂気をある - あなたは、どちらの場合も、新しいアルゴリズム

の内側に古い出力を包む状態維持」データベースにPBKDF2-HMAC-SHA-1の結果を格納しているので、次のようになります。

  • パスワードハッシュ(BINARY(20)) - すなわちPBKDF2出力。
  • あなた塩(RNGCryptoServiceProvider Classによって、ユーザーごとに生成BINARY(16)、)
  • オプション:PBKDF2の反復回数(INT、ちょうどあなたのサーバーは、最大でCPUバウンドになるために前に数万人で開始し、上がりますあなたのハードウェアがアップグレードされるにつれて増加します)
    • これは、ユーザーが正しい(正しい)パスワードを入力するたびに透過的にセキュリティレベルを上げることができます。最初に正しいことを検証し、より高い反復回数で再ハッシュします
  • オプション:後で別のアルゴリズムにアップグレードする方が簡単なように「バージョン」(TINYINT)、sin一度に複数のバージョンをアクティブにすることができます。

P.S.バージョン1またはバージョン2の新しいアルゴリズムでは、PBKDF2-HMAC-SHA256、PBKDF2-HMAC-SHA512などの.NETライブラリを作成しました。 my Github repositoryには、テストベクトルの合理的なセットを含むその変形が含まれています。

2

はなぜネット

によって最も簡単な1
public static string HashString(string inputString, string hashName) 
{ 
    var algorithm = HashAlgorithm.Create(hashName); 
    if (algorithm == null) 
    throw new ArgumentException("Unrecognized hash name", hashName); 

    byte[] hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString)); 
    return Convert.ToBase64String(hash); 
} 
+0

はい、HashAlgorithmは非常に柔軟です。私はあなたに同意します。それがSHA1ならば、基本的にはHashAlgorithm.Create( "SHA-1")のようなcreateメソッドに渡されます –