SqlMembershipProvider のハッシュ アルゴリズム

前回の Silverlight Business Application テンプレートの認証機能でパスワードに対するハッシュ アルゴリズムについて少し触れましたが、
今回は SqlMembershipProvider についてより詳しく記述してみます。
 
■ 使用されるハッシュ アルゴリズムを指定する方法
.NET Framework 4 の SqlMembershipProvider が使用するハッシュ アルゴリズムは、次のロジックで決まるようです。
  1. <membership> 要素の hashAlgorithmType 属性が
      a. 指定されているとき、その値。
      b. 指定されていないとき、<membership> – <providers> – <add> 要素の passwordCompatMode 属性が
            i. 指定されていないまたは Framework20 のとき、SHA1。
            ii. Framework40 のとき、<machineKey> 要素の validation 属性の値 (既定では HMACSHA256)。
  2. 上記の結果が MD5、AES または TripleDES のとき、SHA1。
従って、Web.config で何も指定しない場合、Membership.HashAlgorithmType で取得される値が HMACSHA256 であるにもかかわらず、
SqlMembershipProvider が使用するハッシュ アルゴリズムは SHA1 となります。
 
上記で登場した要素や属性をすべて記述した Web.config がこちらです。

  <system.web>
    <machineKey validation="HMACSHA256" />
    <membership defaultProvider="Default" hashAlgorithmType="HMACSHA256">
      <providers>
        <clear />
        <add passwordCompatMode="Framework40"
          name="Default" applicationName="BusinessApplication1" connectionStringName="Business1ConnectionString"
          type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </membership>
  </system.web>

 
passwordCompatMode 属性に指定できるのは、MembershipPasswordCompatibilityMode 列挙体の値です。
passwordCompatMode 属性は .NET Framework 4 で追加された SqlMembershipProvider 固有の属性であり、
まだあまり認知されていないと思いますが、ここに Framework40 を指定しないと validation 属性の値は反映されません。
(今のところ、MSDN ライブラリにもまだ記述がありません。検索してもヒットしません。)
 
結論として、<membership> 要素の hashAlgorithmType 属性を明示的に指定しておくのが一番わかりやすい方法であると考えられます。
逆に、ここの値を指定しておけば他の部分を指定する必要はありません。
 
また、SHA1 については脆弱性が指摘されており、より強度のあるアルゴリズムが推奨されるため、
HMACSHA256 や SHA256 などを指定することが望ましいです。
 
■ ハッシュ化のためのコード
SqlMembershipProvider は、ハッシュの強度を増すために、
ソルトと呼ばれるユーザーごとに与えられるデータと組み合わせてパスワードをハッシュ化します。
 
SqlMembershipProvider では、だいたい以下のような処理が実行されています。
SqlMembershipProvider を使わずに認証ロジックを自作したいという場合にも、これらのコードが参考になると思います。

static void Main()
{
    string hashedPassword = Hash("P@ssw0rd", "j44YfP/l4cC9OTxsBiiQ+w==");
}

private static string hashAlgorithmName = "HMACSHA256"; // 変更可能
private static Encoding encoding = Encoding.Unicode;

public static byte[] Hash(byte[] data, byte[] salt)
{
    using (HashAlgorithm hashAlgorithm = HashAlgorithm.Create(hashAlgorithmName))
    {
        if (hashAlgorithm is KeyedHashAlgorithm)
        {
            KeyedHashAlgorithm keyedHashAlgorithm = (KeyedHashAlgorithm)hashAlgorithm;

            keyedHashAlgorithm.Key = Enumerable.Range(0, keyedHashAlgorithm.Key.Length)
                 .Select(i => salt[i % salt.Length]).ToArray();

            return keyedHashAlgorithm.ComputeHash(data);
        }
        else
        {
            byte[] saltedData = salt.Concat(data).ToArray();

            return hashAlgorithm.ComputeHash(saltedData);
        }
    }
}

public static string Hash(string text, string salt)
{
    return Convert.ToBase64String(Hash(encoding.GetBytes(text), Convert.FromBase64String(salt)));
}

// ランダムなソルトを生成します。
// SqlMembershipProvider では 16 バイトです。
public static string GenerateSalt()
{
    return Convert.ToBase64String(GenerateRandomByteArray(16));
}

// ランダムなバイト配列を生成します。
public static byte[] GenerateRandomByteArray(int size)
{
    byte[] data = new byte[size];

    RandomNumberGenerator.Create().GetBytes(data);

    return data;
}


 
ちなみに、暗号アルゴリズムの名前と具象クラスのマッピングの一覧は、
CryptoConfig クラスの DefaultNameHT プロパティ (プライベートかつ静的) で見ることができます。
 
バージョン情報
.NET Framework 4
 
参照
カテゴリー: .NET Framework. タグ: . 2 Comments »

2件のフィードバック to “SqlMembershipProvider のハッシュ アルゴリズム”

  1. Silverlight Business Application テンプレートの認証機能 « Do Design Space Says:

    […] membership 要素 (ASP.NET 設定スキーマ) 迫りくる「暗号の2010年問題」 SqlMembershipProvider のハッシュ アルゴリズム   カテゴリー: クライアント技術. タグ: .NET RIA Services, Silverlight. […]

  2. 共通鍵 (対称鍵) 暗号化アルゴリズム « Do Design Space Says:

    […] カテゴリー: .NET Framework — sakapon @ 02:11 Tags: 暗号化 前回の SqlMembershipProvider のハッシュ アルゴリズムでは SqlMembershipProvider […]


コメントを残す