【发布时间】:2012-04-16 22:02:14
【问题描述】:
我觉得这个问题很愚蠢,但由于我不知道答案,所以我还是继续。
我正在尝试一些身份验证代码并想知道为什么我从 Rfc2898DeriveBytes 获得的字节数组需要转换为 HEX 并再次转换回字节数组才能正确初始化我的 HMACSHA1 对象。我觉得我是做一些愚蠢的事情,或者只是错过了一些明显的事情。
我的客户端代码是一个基于crypto-js的javascript函数;
var key256bit = Crypto.PBKDF2(passwordEntered, saltBytes, 32, { iterations: 1000 });
var hmacBytes = Crypto.HMAC(Crypto.SHA1, url, key256bit, { asBytes: true });
var base64Hash = Crypto.util.bytesToBase64(hmacBytes);
我的服务器端代码如下;
Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password,
encoding.GetBytes(salt), 1000);
byte[] key = rfc2898.GetBytes(32);
// Don't think I should need to do this.
// However, it wont work if I initialise HMACSHA1
// with the rfc2898.GetBytes(32)
string test = ByteArrayToString(key);
HMACSHA1 hmacSha1 = new HMACSHA1(encoding.GetBytes(test));
byte[] computedHash = hmacSha1.ComputeHash(encoding.GetBytes(requestUri));
string computedHashString = Convert.ToBase64String(computedHash);
我从网上获取的 ByteArrayToString 方法是;
private static string ByteArrayToString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
所以我可以看到我从对rfc2898.GetBytes(32) 的调用中获得了 32 个字节。我使用 ByteArrayToString 方法将其转换为 HEX,以确认它与我在 Javascript 变量 key256bit 中看到的匹配。现在我的测试变量是一个长度为 64 的字符串,当我使用 encoding.GetBytes(test) 将它传递给 HMACSHA1 的构造函数时,它是一个长度为 64 的字节数组。
crypto-js 上的文档有点欠缺,但我认为调用 Crypto.PBKDF2 的参数为 32,它正在创建一个 32 字节长(或 256 位)的密钥。
非常感谢任何澄清。
【问题讨论】:
-
请在发布代码 sn-ps 时指定您使用的语言。您在客户端使用 JavaScript 并在服务器上使用 Java 并不是很明显。我的意思是,据我所知,您可能正在使用 Dalvik 或 C#。
-
@OldPro:绝对是 C#,而不是 Java。查看“字符串”的大小写、方法名称等
-
是的。绝对是 C#。我没有添加关于语言的标签,因为我的问题已经包含 4 个!另外,我有点怀疑我的问题的根本原因是我对代码中正在进行的转换缺乏了解。我会在接下来的几天里做一些调查并报告。
-
@Jon,我根本不懂 C#。在我粗略的阅读中没有发现细微的差异,这是我的观点。 Moose 先生,我并不是说您需要在标签中添加语言,但正如您所说“我的客户端代码是基于 crypto-js 的 javascript 函数”,如果您说“我的服务器”我会很感激侧面代码是 C# 如下”。这就是我所要求的。抱歉没有说得更清楚。