/// <summary> /// Password entered by the userをDB保存する際、 /// Salted and hashed passwordとして保存する必要がある。 /// </summary> /// <param name="rawPassword">Password entered by the user.</param> /// <param name="ekha">ハッシュ・アルゴリズム列挙型</param> /// <param name="key">キー</param> /// <param name="saltLength">ソルトの文字列長</param> /// <param name="stretchCount">ストレッチ回数</param> /// <returns>Salted and hashed password.</returns> public static string GetSaltedPassword(string rawPassword, EnumKeyedHashAlgorithm ekha, string key, int saltLength, int stretchCount) { // ランダム・ソルト文字列を生成(区切り記号は含まなくても良い) string salt = GetPassword.Generate(saltLength, 0); //Membership.GeneratePassword(saltLength, 0); byte[] saltByte = CustomEncode.StringToByte(salt, CustomEncode.UTF_8); // KeyedHashのキーを生成する。 Rfc2898DeriveBytes passwordKey = new Rfc2898DeriveBytes(key, saltByte, stretchCount); // Salted and hashed password(文字列)を生成して返す。 return // key (CustomEncode.ToBase64String(CustomEncode.StringToByte(key, CustomEncode.UTF_8)) // saltByte + "." + CustomEncode.ToBase64String(saltByte) // stretchCount + "." + CustomEncode.ToBase64String(CustomEncode.StringToByte(stretchCount.ToString(), CustomEncode.UTF_8)) // Salted and hashed password + "." + CustomEncode.ToBase64String( GetPasswordHashV2.GetKeyedHashBytes( CustomEncode.StringToByte(salt + rawPassword, CustomEncode.UTF_8), ekha, passwordKey.GetBytes(24)))); }
/// <summary>パスワードを比較して認証する。</summary> /// <param name="rawPassword">Password entered by the user.</param> /// <param name="saltedPassword">Salted and hashed password.</param> /// <param name="ekha">ハッシュ・アルゴリズム列挙型</param> /// <returns> /// true:パスワードは一致した。 /// false:パスワードは一致しない。 /// </returns> public static bool EqualSaltedPassword(string rawPassword, string saltedPassword, EnumKeyedHashAlgorithm ekha) { // ソルト部分を取得 string[] temp = saltedPassword.Split('.'); // key string key = CustomEncode.ByteToString(CustomEncode.FromBase64String(temp[0]), CustomEncode.UTF_8); // saltByte byte[] saltByte = CustomEncode.FromBase64String(temp[1]); // salt string salt = CustomEncode.ByteToString(saltByte, CustomEncode.UTF_8); // stretchCount int stretchCount = int.Parse(CustomEncode.ByteToString(CustomEncode.FromBase64String(temp[2]), CustomEncode.UTF_8)); // Salted and hashed password string hashedPassword = temp[3]; // KeyedHashのキーを生成する。 Rfc2898DeriveBytes passwordKey = new Rfc2898DeriveBytes(key, saltByte, stretchCount); // 引数のsaltedPasswordと、rawPasswordから自作したsaltedPasswordを比較 string compare = CustomEncode.ToBase64String( GetPasswordHashV2.GetKeyedHashBytes( CustomEncode.StringToByte(salt + rawPassword, CustomEncode.UTF_8), ekha, passwordKey.GetBytes(24))); if (hashedPassword == compare) { // 一致した。 return(true); } else { // 一致しなかった。 return(false); } }
/// <summary> /// Password entered by the userをDB保存する際、 /// Salted and hashed passwordとして保存する必要がある。 /// </summary> /// <param name="rawPassword">>Password entered by the user.</param> /// <param name="eha">ハッシュ・アルゴリズム列挙型</param> /// <param name="saltLength">ソルトの文字列長</param> /// <returns>Salted and hashed password.</returns> /// <see ref="http://www.atmarkit.co.jp/ait/articles/1110/06/news154_2.html"/> public static string GetSaltedPassword(string rawPassword, EnumHashAlgorithm eha, int saltLength) { // overloadへ return(GetPasswordHashV2.GetSaltedPassword(rawPassword, eha, saltLength, 1)); }