如何重现由asp.net MVC默认成员资格创建的密码哈希

时间:2012-12-26 08:15:25

标签: asp.net asp.net-mvc hash asp.net-mvc-4 asp.net-membership

我使用asp.net MVC 4默认会员系统,而客户端需要发送包含他的哈希密码的签名,用于身份验证。

我需要将密码与服务器的哈希密码一样哈希。

    private static bool IsAuthenticated(string hashedPassword, string message, string signature)
    {
        if (string.IsNullOrEmpty(hashedPassword))
            return false;

        var verifiedHash = ComputeHash(hashedPassword, message);
        if (signature != null && signature.Equals(verifiedHash))
            return true;

        return false;
    }

那么如何在数据库中重现像存储密码这样的哈希密码呢?

4 个答案:

答案 0 :(得分:1)

我不确定我是否理解你的问题,但是没有必要比较散列密码。会员资格已经有了验证用户的方法,您应该只使用

Membership.ValidateUser(username, password)

如果您使用的是会员提供者和表单身份验证,则可以检查用户是否已登录

 User.Identity.IsAuthenticated

答案 1 :(得分:1)

请参阅类System.Web.Helpers.Crypto 方法 HashPassword 方法。 SimpleMemberShip提供程序将此类用于加密服务。

你可以从DB中读取条目: - )

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.web.helpers.crypto%28v=vs.111%29.aspx

顺便说一句,别忘了考虑盐。您的流程是否要求您在散列之前组合Pass和salt?

答案 2 :(得分:1)

.net成员资格提供程序使用base64编码的HMACSHA1哈希值。您可以在客户端使用javascript重新创建相同的哈希值。诀窍是确保您的密码和散列密钥相同并使用utf-16le编码。这是使用crypto-js的解决方案。不知道为什么crypto-js utf-16le函数没有产生相同的结果所以我使用的是不同的utf函数。

//not sure why crypt-js's utf16LE function doesn't give the same result
//words = CryptoJS.enc.Utf16LE.parse("test");
//utf16 = CryptoJS.enc.Utf16LE.stringify("test");

function str2rstr_utf16le(input) {
  var output = [],
      i = 0,
      l = input.length;

  for (; l > i; ++i) {
    output[i] = String.fromCharCode(
      input.charCodeAt(i)        & 0xFF,
      (input.charCodeAt(i) >>> 8) & 0xFF
    );
  }

  return output.join('');
}

var pwd = str2rstr_utf16le("test");
var hash = CryptoJS.HmacSHA1(pwd, pwd);

var encodedPassword = CryptoJS.enc.Base64.stringify(hash);

答案 3 :(得分:0)

来自Crypto.cs @ System.Web.Helpers的完整方法:

/// <summary>Returns an RFC 2898 hash value for the specified password.</summary>
/// <returns>The hash value for <paramref name="password" /> as a base-64-encoded string.</returns>
/// <param name="password">The password to generate a hash value for.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="password" /> is null.</exception>
public static string HashPassword(string password)
{
  if (password == null)
    throw new ArgumentNullException("password");
  byte[] salt;
  byte[] bytes;
  using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 16, 1000))
  {
    salt = rfc2898DeriveBytes.Salt;
    bytes = rfc2898DeriveBytes.GetBytes(32);
  }
  byte[] inArray = new byte[49];
  Buffer.BlockCopy((Array) salt, 0, (Array) inArray, 1, 16);
  Buffer.BlockCopy((Array) bytes, 0, (Array) inArray, 17, 32);
  return Convert.ToBase64String(inArray);
}