【问题标题】:using cryptojs to generate RFC 2104-compliant HMAC with SHA256 algorithm使用 cryptojs 使用 SHA256 算法生成符合 RFC 2104 的 HMAC
【发布时间】:2017-08-19 00:33:21
【问题描述】:

我正在关注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=

嗯,有谁知道怎么回事?

【问题讨论】:

    标签: javascript amazon-web-services cryptojs


    【解决方案1】:
     let hash = CryptoJS.HmacSHA256(message, secret_key);
     let result = CryptoJS.enc.Base64.stringify(hash);
    

    我在这里发布这个解决方案是因为我试图在 ReactNative 中做同样的练习,而 ReactNative 不喜欢 npm 的基本加密包。 CryptoJS 可以作为替代品。

    注意:(这太让人生气了)我不得不去掉第一个 \n,尽管亚马逊明确告诉你在行前加上换行符,并且在他们的示例中 GET 在其上方有一个行空间..

    完整解决方案:

     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);
    

    【讨论】:

      【解决方案2】:

      没有错,只是你得到的字符串代表一个字节数组(用它们的十六进制表示)。因此,您需要做的就是对这个字节数组进行 Base 64 编码,您将得到完全相同的结果。在此处查看,粘贴您的十六进制表示的字节数组并以 64 为基数对其进行编码:http://tomeko.net/online_tools/hex_to_base64.php?lang=en

      至于如何做到这一点,你可以看看this questionthis one


      更新:

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

      console.log(signature2.toString(CryptoJS.enc.Base64));
      

      【讨论】:

      • console.log(signature2.toString(CryptoJS.enc.Base64));
      • 哦,很高兴知道有一种内置的方法可以实现这一点。感谢您指出了这一点。我将更新我的答案以包含此信息。
      • 没关系。请注意,可能需要加载 enc-base64.min.js。
      猜你喜欢
      • 2013-05-12
      • 2010-11-17
      • 1970-01-01
      • 2016-08-20
      • 2023-02-23
      • 2013-07-29
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      相关资源
      最近更新 更多