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

那么如何重现散列密码,如数据库中存储的密码?

4

4 回答 4

1

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

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

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

顺便说一句,不要忘记考虑 SALT。您的过程是否要求您在散列之前结合 Pass 和 salt ?

于 2012-12-30T06:25:30.377 回答
1

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

Membership.ValidateUser(username, password)

如果您正在使用会员资格提供程序和表单身份验证,那么您可以检查用户是否已经登录

 User.Identity.IsAuthenticated
于 2012-12-30T02:17:48.480 回答
0

.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);
于 2013-01-11T17:52:32.517 回答
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);
}
于 2017-06-21T07:42:42.243 回答