NodeJS crypto.createHmac SHA256 无法正常工作
NodeJS crypto.createHmac SHA256 not working properly
我目前正在尝试实现我们正在使用的库的身份验证部分,但我偶然发现了一个关于数据签名的奇怪问题,crypto.createHmac 在 NodeJS 中的输出大致是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 上托管我们的 NodeJS 后端,顺便说一句,不确定这是否相关但似乎至少值得一提。
编辑:
我发现了问题,PHP 中的 hash_hmac 自动将其数据导出为十六进制数据,crypto.createHmac 将其数据导出为原始二进制数据,我直接将其转换为 base64,我需要做的就是首先将数据导出为十六进制,然后将其转换为 base64。
试试这个;
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'))
对于 Azure,您提到密钥以 Base64 格式提供。对于节点的 cryto 库,当我将密钥作为缓冲区传递时,我发现它有效。 Azure 授权签名 header 节点代码示例如下:
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);
我目前正在尝试实现我们正在使用的库的身份验证部分,但我偶然发现了一个关于数据签名的奇怪问题,crypto.createHmac 在 NodeJS 中的输出大致是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 上托管我们的 NodeJS 后端,顺便说一句,不确定这是否相关但似乎至少值得一提。
编辑:
我发现了问题,PHP 中的 hash_hmac 自动将其数据导出为十六进制数据,crypto.createHmac 将其数据导出为原始二进制数据,我直接将其转换为 base64,我需要做的就是首先将数据导出为十六进制,然后将其转换为 base64。
试试这个;
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'))
对于 Azure,您提到密钥以 Base64 格式提供。对于节点的 cryto 库,当我将密钥作为缓冲区传递时,我发现它有效。 Azure 授权签名 header 节点代码示例如下:
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);