使用 cryptojs 使用 SHA256 算法生成符合 RFC 2104 的 HMAC
using cryptojs to generate RFC 2104-compliant HMAC with SHA256 algorithm
我正在关注 this amazon documentation,试图找到在 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());
我得到 8fb6d93342d767d797799aee4ea5a6d8322f0d8554537c313cfa69fa25f1cd07
我应该得到 j7bZM0LXZ9eXeZruTqWm2DIvDYVUU3wxPPpp+iXxzQc=
嗯,有人知道怎么了吗?
没什么问题,只是你得到的字符串代表一个字节数组(用十六进制表示)。因此,您需要做的就是对这个字节数组进行 Base 64 编码,您将获得完全相同的结果。在这里签出,粘贴您的十六进制表示的字节数组并对其进行 base 64 编码:http://tomeko.net/online_tools/hex_to_base64.php?lang=en
至于如何做到这一点,嗯,你可以看看this question or this one。
更新:
正如评论中指出的那样,cryptojs 中似乎有一种内置方法可以直接转换为 base64:
console.log(signature2.toString(CryptoJS.enc.Base64));
let hash = CryptoJS.HmacSHA256(message, secret_key);
let result = CryptoJS.enc.Base64.stringify(hash);
我在这里发布这个解决方案是因为我试图在 ReactNative 中做这个完全相同的练习,而 ReactNative 不喜欢 npm 的基本加密包。 CryptoJS 作为替代品工作。
注意:(这真令人气愤)我不得不去掉第一个 \n,尽管亚马逊特别告诉您在行前添加换行符,并且 GET 在他们的示例中在其上方有一行 space ..
完整解决方案:
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);
我正在关注 this amazon documentation,试图找到在 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());
我得到 8fb6d93342d767d797799aee4ea5a6d8322f0d8554537c313cfa69fa25f1cd07
我应该得到 j7bZM0LXZ9eXeZruTqWm2DIvDYVUU3wxPPpp+iXxzQc=
嗯,有人知道怎么了吗?
没什么问题,只是你得到的字符串代表一个字节数组(用十六进制表示)。因此,您需要做的就是对这个字节数组进行 Base 64 编码,您将获得完全相同的结果。在这里签出,粘贴您的十六进制表示的字节数组并对其进行 base 64 编码:http://tomeko.net/online_tools/hex_to_base64.php?lang=en
至于如何做到这一点,嗯,你可以看看this question or this one。
更新:
正如评论中指出的那样,cryptojs 中似乎有一种内置方法可以直接转换为 base64:
console.log(signature2.toString(CryptoJS.enc.Base64));
let hash = CryptoJS.HmacSHA256(message, secret_key);
let result = CryptoJS.enc.Base64.stringify(hash);
我在这里发布这个解决方案是因为我试图在 ReactNative 中做这个完全相同的练习,而 ReactNative 不喜欢 npm 的基本加密包。 CryptoJS 作为替代品工作。
注意:(这真令人气愤)我不得不去掉第一个 \n,尽管亚马逊特别告诉您在行前添加换行符,并且 GET 在他们的示例中在其上方有一行 space ..
完整解决方案:
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);