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

4
我使用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;
    }

那么我如何复制数据库中存储的哈希密码?


1
我不确定你在这里想做什么,但它看起来非常错误和不安全。asp.net提供了机制来确定用户是否已经通过身份验证。这似乎是一个XY问题(即,你问如何做一些愚蠢的事情,因为你已经说服自己做这件愚蠢的事情会解决你的真正问题。相反,你应该询问你的真正问题,这似乎是如何告诉用户是否已经通过身份验证。 - Erik Funkenbusch
4个回答

1

我不确定我是否理解了你的问题,但是没有必要比较哈希密码。会员已经有一种验证用户的方法,你应该直接使用它。

Membership.ValidateUser(username, password)

如果您正在使用会员提供程序和表单身份验证,则可以检查用户是否已登录。
 User.Identity.IsAuthenticated

1
我认为意图是如何在不依赖于 .net 成员资格类的情况下创建哈希,以便可以在其他系统中完成。 - MonkeyBonkey

1

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);
}

0

.net Membership提供程序使用一个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);

太好了。我正想问一下,如何在一个ASP.Net到Node的移植项目中用JS重建此过程。谢谢! - user358089

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接