Javascript 使用cryptojs使用SHA256算法生成符合RFC2104的HMAC

Javascript 使用cryptojs使用SHA256算法生成符合RFC2104的HMAC,javascript,amazon-web-services,cryptojs,Javascript,Amazon Web Services,Cryptojs,我正在尝试寻找用javascript生成签名的算法。我似乎无法让它工作 // html // <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/sha256.min.j

我正在尝试寻找用javascript生成签名的算法。我似乎无法让它工作

// html
// <head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/sha256.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac.min.js"></script>
// body (javascript)
var test_string = "GET\nwebservices.amazon.com\n/onca/xml\nAWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&AssociateTag=mytag-20&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers%2CReviews&Service=AWSECommerceService&Timestamp=2014-08-18T12%3A00%3A00Z&Version=2013-08-01"

var signature2 = CryptoJS.HmacSHA256(test_string, "1234567890");
console.log(signature2.toString());
//html
// 
//正文(javascript)
var test_string=“GET\nwebservices.amazon.com\n/onca/xml\nAWSAccessKeyId=akaiosfodnn7example&AssociateTag=mytag-20&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=Images%2citemtattributes%2COffers%2CReviews&Service=awsecomerceservice&Timestamp=2014-08-18T12%3A00%3A00Z&Version=2013-08-01”
var signature2=CryptoJS.HmacSHA256(测试字符串,“1234567890”);
log(signature2.toString());
我得到了
8fb6d93342d767d797799aee4ea5a6d8322f0d8554537c313cfa69fa25f1cd07

我应该得到
J7BZM0LXZ9EXEZRUTQWM2DIVDYVU3WXPPPP+iXxzQc=


嗯,有人知道怎么回事吗?

没什么错,只是你得到的字符串代表一个字节数组(用十六进制表示)。因此,您只需对这个字节数组进行base64编码,就可以得到完全相同的结果。在此处签出,粘贴十六进制表示的字节数组,并对其进行base 64编码:

至于如何做到这一点,好吧,你可以看看或


更新:

正如评论中指出的,cryptojs中似乎有一种内置的方式可以直接转换为base64:

console.log(signature2.toString(CryptoJS.enc.Base64));
我在这里发布这个解决方案,因为我试图在ReactNative中进行完全相同的练习,ReactNative不喜欢npm的基本加密包。CryptoJS作为替代品工作

注意:(这让人恼火)我不得不去掉第一个,尽管Amazon特别告诉您在行前面加上分隔符,并且在他们的示例中,get上面有一个行空间

完整解决方案:


console.log(signature2.toString(CryptoJS.enc.Base64))哦,很高兴知道有一个内置的方法来实现这一点。谢谢你指出这一点。我会更新我的答案以包含这些信息。没关系。请注意,可能需要加载enc-base64.min.js。
 let hash = CryptoJS.HmacSHA256(message, secret_key);
 let result = CryptoJS.enc.Base64.stringify(hash);
 let secret_key = "1234567890";
 let message = 'GET' +
 '\nwebservices.amazon.com' +
 '\n/onca/xml' +
 '\nAWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&AssociateTag=mytag-20&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers%2CReviews&Service=AWSECommerceService&Timestamp=2014-08-18T12%3A00%3A00Z&Version=2013-08-01'

 let hash = CryptoJS.HmacSHA256(message, secret_key);
 let result = CryptoJS.enc.Base64.stringify(hash);
 console.log('MARK: RESULT ', result);