我使用Crypto-JS v2.5.3(hmac.min.js)http://code.google.com/p/crypto-js/库来计算客户端哈希,脚本是:
$("#PasswordHash").val(Crypto.HMAC(Crypto.SHA256, $("#pwd").val(), $("#PasswordSalt").val(), { asByte: true }));
这会返回这样的内容:
b3626b28c57ea7097b6107933c6e1f24f586cca63c00d9252d231c715d42e272
然后在服务器端,我使用以下代码来计算哈希:
private string CalcHash(string PlainText, string Salt) {
string result = "";
ASCIIEncoding enc = new ASCIIEncoding();
byte[]
baText2BeHashed = enc.GetBytes(PlainText),
baSalt = enc.GetBytes(Salt);
System.Security.Cryptography.HMACSHA256 hasher = new HMACSHA256(baSalt);
byte[] baHashedText = hasher.ComputeHash(baText2BeHashed);
result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x")).ToArray());
return result;
}
并返回此方法:
b3626b28c57ea797b617933c6e1f24f586cca63c0d9252d231c715d42e272
如您所见,服务器端方法忽略了一些零字符。问题出在哪儿?我的服务器端方法有任何问题吗?我只需要这两个值与相等的字符串和盐相同。
答案 0 :(得分:4)
如您所见,服务器端方法忽略了一些零字符。问题出在哪里?
此处 - 您在C#中转换为十六进制:
b => b.ToString("x")
如果b
为10,则只会给出“a”而不是“0a”。
我个人建议更简单的十六进制转换:
return BitConverter.ToString(baHashedText).Replace("-", "").ToLowerInvariant();
(你可能只需将"x"
改为"x2"
,而是指定2个字符的长度,但它仍然是一种稍微迂回的方式来执行字节到 - 十六进制转换。)
答案 1 :(得分:2)
其他人一直建议使用BitConverter和修剪“ - ”或使用ToString(x2)
之类的东西。有一个更好的解决方案,一个自1.1 SoapHexBinary以来一直在.NET中的类。
using System.Runtime.Remoting.Metadata.W3cXsd2001;
public byte[] StringToBytes(string value)
{
SoapHexBinary soapHexBinary = SoapHexBinary.Parse(value);
return soapHexBinary.Value;
}
public string BytesToString(byte[] value)
{
SoapHexBinary soapHexBinary = new SoapHexBinary(value);
return soapHexBinary.ToString();
}
这将生成您想要的确切格式。
答案 2 :(得分:1)
我认为问题在于:
result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x")).ToArray());
将其更改为:
result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x2")).ToArray());