使用HMAC对base64数据编码问题

时间:2016-09-16 21:55:26

标签: node.js

使用Nodejs,我尝试生成XML消息的HMAC SHA256,base64编码签名。我目前使用PHP进行签名生成。

这个过程看起来相当简单,我可以使用Nodejs生成base64编码的值,但由于某种原因,该值不匹配,并且比使用PHP得到的值短得多。

下面,我已经包含了一个示例PHP脚本和结果以及Nodejs实现和结果。使用Nodejs,我使用本机加密模块。

// PHP implementation

$xml = <<<EOD
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <record>
    <id>1</id>
    <first_name>Carlos</first_name>
    <last_name>Ruiz</last_name>
    <email>cruiz0@engadget.com</email>
    <gender>Male</gender>
    <ip_address>156.225.191.154</ip_address>
  </record>
</dataset>
EOD;

$secret = 'secret';
$sig = base64_encode(hash_hmac('sha256', $xml, $secret));

echo $sig;

结果: ODhkYTc1YmQzNzc0NWUyNDJlNjY3YTY1NzZhYzFhZGYwOTJlMTIxODdjNzYxOWYyNGQxNGExOGVkYTIyZDQ0ZQ==

// Nodejs implementation

var crypto = require('crypto');

fs.readFile('example.xml', 'utf-8', function(err, data) {
  function sig(str, key) {
    return crypto.createHmac('sha256', key)
      .update(str)
      .digest('base64');
  }
  console.log(sig(data, 'secret'));
});

结果: iNp1vTd0XiQuZnpldqwa3wkuEhh8dhnyTRShjtoi1E4=

我花了一天时间试图解决这个问题,经过一年+使用Stack Overflow后,这是我的第一个问题。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

这里的问题是PHP的hash_hmac()默认返回一个十六进制编码的字符串(参见$raw_output参数here),所以你是base64编码一个十六进制字符串而不是原始二进制结果的实际值。

所以改变这个:

$sig = base64_encode(hash_hmac('sha256', $xml, $secret));

为:

$sig = base64_encode(hash_hmac('sha256', $xml, $secret, true));