节点密码Crypto createHmac()输出是否与具有相同输入的PHP hash_hmac()输出不同?

时间:2018-12-10 05:19:37

标签: php node.js

我正在尝试在Node中复制PHP哈希生成函数。此哈希用作API的一部分。 PHP版本会创建系统接受的正确输出。尽管我认为功能上的输入是相同的,但Node版本却创建了不同的输出。

这是因为PHP和Node HMAC函数的工作方式根本不同吗?还是因为我只是想念一些带有字符编码的怪癖?还是我只是弄乱了其他东西?


PHP代码

str.count(_.isDigit)

Node.js代码

$url = 'https://example.com/api/endpoint';
$user = 'apiuser';

// Example key
$key = '+raC8YR2F+fZypNJ5q+CAlqLFqNN1AlAfWwkwJLcI7jrAvppjRPikWp523G/u0BLSpN9+2LusJvpSwrfU9X2uA==';

$timestamp = gmdate('D, d M Y H:i:s T', 1543554184); // gmdate('D, d M Y H:i:s T');

$hashdata = "GET\n$url\n$user\n$timestamp\n";

print_r($hashdata);
/*
GET
https://example.com/api/endpoint
apiuser
Fri, 30 Nov 2018 05:03:04 GMT
*/

$decoded_key = base64_decode($key);

print_r(unpack('H*', $decoded_key));
// Array ( [1] => fab682f1847617e7d9ca9349e6af82025a8b16a34dd409407d6c24c092dc23b8eb02fa698d13e2916a79db71bfbb404b4a937dfb62eeb09be94b0adf53d5f6b8 )

$generated_hash = hash_hmac('sha256', $hashdata, $decoded_key, true);

$encoded_hash = base64_encode($generated_hash);

print_r($encoded_hash);
// vwdT8XhtSA1q+JvAfsRpJumfI4pemoaNFbjjc5JFsvw=

除HMAC函数输出外,其他所有内容都相同。

操作系统:Windows 10-64位

Node.js版本:v10.13.0

PHP版本:7.2.7

1 个答案:

答案 0 :(得分:2)

我可以通过在{.1}中保留decoded_key并将其作为Buffer的形式直接发送到Buffer来在Node.js中获得正确的结果:

crypto.createHmac

此功能受支持,请参见crypto.createHmac

let decoded_key = Buffer.from(api_key, 'base64');
const hmac = crypto.createHmac('sha256', decoded_key);

结果为key <string> | <Buffer> | <TypedArray> | <DataView> -与PHP相同。
工作示例:https://repl.it/repls/DisguisedBlankTechnologies

问题必须出在vwdT8XhtSA1q+JvAfsRpJumfI4pemoaNFbjjc5JFsvw=上。我没有找到将其编码为字符串的其他编码,但是它和.toString('utf8')一样有效。

出于完整性考虑,加密模块还支持另一个选项:

Buffer

工作示例:https://repl.it/repls/LightcoralUnwelcomeProfessionals