我目前正在尝试实施我们正在使用的库的身份验证部分,但我偶然发现了一个奇怪的数据签名问题,即NodeJS中crypto.createHmac的输出大约是PHP中hash_hmac大小的一半,这是PHP和NodeJS之间不同的数据的唯一部分(我们需要在这里使用NodeJS)
用于在NodeJS中创建签名的确切代码是
authorization["oauth_signature"] = crypto.createHmac('SHA256', process.env.SECRET).update(toSign).digest('base64');
对于PHP来说,它是
$authorization["oauth_signature"] = base64_encode(hash_hmac("SHA256", $signatureString . $signingKey, $secret));
然而,NodeJS版本的输出是
7LkQP+qKR1gSdPq/AgH/3No3ps7EtZXnqwjivMixvM8=
对于PHP来说,它是
NmQ0MWIzYmJiMjI2YzFlMDhiYzY3NzVmMWY0MzEwNDlhNDU3NDI0ZGJlMzU3NjJhYmMwYjgwYzZjMDE4NDM4OA==
其中数据增加了两倍
我是否必须为NodeJS版本使用不同的库而不是构建在一个版本中?我们在Microsoft Azure btw上托管我们的NodeJS后端,不确定这是否相关,但似乎至少可以提及。
编辑:
我发现了这个问题,PHP中的hash_hmac自动将其数据输出为十六进制数据,crypto.createHmac将其数据导出为原始二进制数据,我将其直接转换为base64,所有我需要做的是首先将数据导出为十六进制,然后将其转换为base64。
答案 0 :(得分:4)
试试这个;
var crypto = require('crypto');
var s = 'The quick brown fox jumps over the lazy dog';
console.log(
new Buffer(
crypto.createHmac('SHA256', 'SECRET').update(s).digest('hex')
).toString('base64')
);
PHP等价物;
base64_encode(hash_hmac("SHA256",'The quick brown fox jumps over the lazy dog', 'SECRET'))
答案 1 :(得分:0)
对于Azure,您提到密钥以Base64格式提供。使用节点的cryto库,当我将密钥作为Buffer传递时,它发现它有效。以下Azure授权签名标头节点代码示例:
const util = require('util');
const crypto = require('crypto');
var accountName = "YOUR_ACCOUNT_NAME";
var key = Buffer("YOUR_BASE64_KEY",'base64');
var hash = crypto.createHmac('sha256',key).update(stringToSign,'utf8').digest('base64');
var signature = util.format("%s:%s", accountName, hash);
var authorization = util.format("SharedKey %s", signature);