【问题标题】:Javascript: Equivalent of PHP's hash_hmac() with RAW BINARY output?Javascript:相当于 PHP 的 hash_hmac() 与 RAW BINARY 输出?
【发布时间】:2012-08-19 09:49:37
【问题描述】:

我正在连接到亚马逊产品广告 API,为了签署我的请求,我需要对 HMAC-SHA256 哈希的原始二进制输出进行 base64 编码。

the PHP documentation for hash_hmac 中,第四个参数bool $raw_output 控制输出是原始二进制数据(真)还是小写十六进制(假)。只需将该参数设置为 true,我的程序就可以在 PHP 中运行。

但是,我现在正在尝试将其移植到 Javascript。我尝试使用 CryptoJS.HmacSHA256() 函数,但它似乎返回了小写十六进制。如何将其转换为二进制?

我根据 CryptoJS 文档尝试了以下方法,但两个输出是相同的:

var hash = CryptoJS.HmacSHA256("hello", "key");
console.log(hash.toString());
console.log(hash.toString(CryptoJS.enc.Base64));

【问题讨论】:

    标签: php javascript binary base64 amazon-product-api


    【解决方案1】:

    这对我有用:

    var CryptoJS = require("crypto-js");
    const raw_signature = hmacSHA1(baseString, signingKey);
    const signature = raw_signature.toString(CryptoJS.enc.Base64);
    

    它给出的结果与 PHP 中的结果完全相同:

    $rawSignature = hash_hmac("sha1", $baseString, $signingKey, true);
    $signature    = base64_encode($rawSignature);
    

    【讨论】:

      【解决方案2】:

      你也可以使用这个 npm 包在 Javascript 中做同样的事情。

      var jsSHA = require('jssha');
      
      hmac_sha1(string, key){
          let shaObj = new jsSHA("SHA-1", "TEXT");
          shaObj.setHMACKey(key, "TEXT");
          shaObj.update(string);
          let hmac = shaObj.getHMAC("B64");
          return hmac;
      };
      

      【讨论】:

        【解决方案3】:

        PHP:

        base64_encode(hash_hmac('sha256', $value, $key, true));
        

        Nodejs 等价物:

        const crypto = require('crypto');
        let token = crypto.createHmac("sha256", key).update(value).digest().toString('base64');
        

        【讨论】:

          【解决方案4】:

          php代码

          echo base64_encode(hash_hmac('SHA1', 'shanghai', '0', true).'beijing');
          

          php 输出

          xvBv49PpaYvXAIfy3iOSDWNQj89iZWlqaW5n
          

          节点代码

          var crypto = require('crypto');
          var buf1 = crypto.createHmac("sha1", "0").update("shanghai").digest();
          var buf2 = Buffer.from('beijing');
          console.log(Buffer.concat([buf1, buf2]).toString('base64'));    
          

          节点输出

          xvBv49PpaYvXAIfy3iOSDWNQj89iZWlqaW5n
          

          【讨论】:

          • 你的代码不清楚,key是什么,value是什么?
          【解决方案5】:

          这在他们的documentation 中有解释。试试这个:

          var hash = CryptoJS.HmacSHA256("Message", "Secret Passphrase");
          
          var base64 = hash.toString(CryptoJS.enc.Base64);
          

          您需要为此添加http://crypto-js.googlecode.com/svn/tags/3.0.2/build/components/enc-base64-min.js。如果你没有包含这个,CryptoJS.enc.Base64 将是 undefined 并回退到默认值。

          工作演示:http://jsfiddle.net/ak5Qm/

          【讨论】:

          • 我已经试过了,好像不行。请参阅我修改后的问题以获得更好的解释。
          • @Kevin 您是否包含了 base64-min.js?因为它在这里工作正常:jsfiddle.net/ak5Qm
          • @Kevin 如果您使用 google chrome,请在页面加载时按 ctrl+shift+j 并查看是否有错误。您也可以在控制台中简单地写CryptoJS.enc.Base64 以查看它是否为undefined
          • 原来我的脚本包含在错误的顺序中:enc-base64 THEN hmac-sha256,而不是反之亦然。切换这个顺序解决了这个问题。再次感谢!
          • @Esailija 我认为更长的小提琴奏效。看起来 Google 移动了这些脚本
          猜你喜欢
          • 2016-06-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-27
          • 1970-01-01
          • 2013-07-14
          • 2010-11-24
          • 1970-01-01
          相关资源
          最近更新 更多