简体   繁体   中英

Transcription of hash_hmac and hex2bin PHP functions to NodeJS

I have a PHP script which use HMAC and a key to generate a hash. It works well:

$payload = '1605697463367HELLO';
$key = '861bbfc01e089259091927d6ad7f71c8b46b7ee13499574e83c633b74cdc29e3b7e262e41318c8425c520f146986675fdd58a4531a01c99f06da378fdab0414a';
$expected_result = '82ef9a8178dcb4df0b71540fa06d7da826ecb26e1977e230bdc8c9d6f9f1af84';

print_r([
    hash_hmac('sha256', $payload, $key),
    hash_hmac('sha256', $payload, hex2bin($key)),
    $expected_result
]);
/*
Array
(
    [0] => 466d4640b64eecc71e8a2dbd3bafdda0118295e07214e7a7845189699fcf7aa5
    [1] => 82ef9a8178dcb4df0b71540fa06d7da826ecb26e1977e230bdc8c9d6f9f1af84
    [2] => 82ef9a8178dcb4df0b71540fa06d7da826ecb26e1977e230bdc8c9d6f9f1af84
)
GOOD! [1] matches [2]!
*/

Now I need to translate this into NodeJS. I tried without success these solutions:

const crypto = require('crypto');
const { TextEncoder } = require('util');
const { HmacSHA256 } = require('crypto-js');
const hex2bin = str => str.match(/.{1,2}/g).reduce((str, hex) => str += String.fromCharCode(parseInt(hex, 16)), '');

const payload = '1605697463367HELLO';
const key = '861bbfc01e089259091927d6ad7f71c8b46b7ee13499574e83c633b74cdc29e3b7e262e41318c8425c520f146986675fdd58a4531a01c99f06da378fdab0414a';
const expected_result = '82ef9a8178dcb4df0b71540fa06d7da826ecb26e1977e230bdc8c9d6f9f1af84';

console.log([
    crypto.createHmac('SHA256', key).update(payload).digest('hex'),
    crypto.createHmac('SHA256', hex2bin(key)).update(payload).digest('hex'),
    HmacSHA256(payload, key).toString(),
    HmacSHA256(payload, hex2bin(key)).toString(),
    HmacSHA256((new TextEncoder()).encode(payload), key).toString(),
    HmacSHA256((new TextEncoder()).encode(payload), hex2bin(key)).toString(),
    expected_result
]);
/*
[ '466d4640b64eecc71e8a2dbd3bafdda0118295e07214e7a7845189699fcf7aa5',
  'ccaa5b655b83f958eb8639e3fe8e6d0a2933b00779f5b84772bec89ba59a31d0',
  '466d4640b64eecc71e8a2dbd3bafdda0118295e07214e7a7845189699fcf7aa5',
  'ccaa5b655b83f958eb8639e3fe8e6d0a2933b00779f5b84772bec89ba59a31d0',
  '7f618537b8994815ac5a2ca347bc13709b7ccd722565832e800c9f824c1f722c',
  'e438ef17a0307ce1b9b42ed3f892f0009027879d21fa70c38175826f981d0eca',
  '82ef9a8178dcb4df0b71540fa06d7da826ecb26e1977e230bdc8c9d6f9f1af84' ]
BAD! no log matches the last!
*/

What do I miss? Thanks for your help

EDIT : added a log for PHP without hex2bin for the key

@svgta pointed that the hex2bin function in JS may be broken. I found it somewhere on the web, but it was indeed broken.

Here is the hex2bin function that worked for me (found here https://stackoverflow.com/a/65160900/2030095 )

const hex2bin = hex => {
    const length = hex.length / 2;
    const result = new Uint8Array(length);
    for (let i = 0; i < length; i += 1) {
        result[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
    }
    return result;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM