我使用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;
}
那么如何在数据库中重现像存储密码这样的哈希密码呢?
答案 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);
}