在Javascript中创建C#生成的HMAC哈希

3
我有下面这个C#函数;
private string GetEncyptionData(string encryptionKey)
    {
        string hashString = string.Format("{{timestamp:{0},client_id:{1}}}", Timestamp, ClientId);
        HMAC hmac = HMAC.Create();
        hmac.Key = Guid.Parse(encryptionKey).ToByteArray();
        byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(hashString));
        string encData = Convert.ToBase64String(hash);
        return encData;
    }

我正在尝试将这段代码转换为JavaScript。我找到了一个助手库(点击此处)
以下是我正在使用的代码:
 <script>
            var timestamp = 1424890904;
            var client_id = "496ADAA8-36D0-4B65-A9EF-EE4E3659910D";
            var EncryptionKey = "E69B1B7D-8DFD-4DEA-824A-8D43B42BECC5";

            var message = "{timestamp:{0},client_id:{1}}".replace("{0}", timestamp).replace("{1}", client_id);

            var hash = CryptoJS.HmacSHA1(message, EncryptionKey);
            var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);       

             alert(hashInBase64);
        </script>

但是上面的代码并没有从C#代码中生成相同的输出。如何在Javascript中实现?

你确定加密密钥和时间戳完全正确吗?这是过去常常让我犯错的地方...此外,比较哈希之前和之后的值,以及 base64 转换之前和之后的值,看看差异在哪里。 - Brian Mains
1个回答

3
你的问题是由于密钥导致的。在C#中,你传递了一个16字节的数组作为密钥。而在CryptoJS中,你传递了一个字符串,CryptoJS将其解释为口令,因此它会生成与之完全不同的密钥。
编辑:以下是如何在javascript中获取正确密钥:
如果你将16字节的密钥转换为Base64,在javascript中可以执行以下操作。它将生成一个WordArray作为密钥,并使用该密钥生成哈希值。
var keyBase64 = "eFY0EiMBZ0UBI0VniRI0Vg==";
var key = CryptoJS.enc.Base64.parse(keyBase64);
var hash = CryptoJS.HmacSHA1("Hello", key);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash); 
console.log(hashInBase64);

非常好用。我希望我能有JavaScript等效的Guid.Parse(encryptionKey).ToByteArray();但无论如何,现在我会手动转换它。 - Teoman shipahi
CryptoJS可能有一些可以做到这一点的东西——我没有深入研究他们的辅助库。 - Joe Enos

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