1
votes

I need to calculate the HMAC-sha256 signature in JavaScript. I am using the following code.

crypto.createHmac('sha256','abc123').update('{"video-id":"212zpS6bjN77eixPUMUEjR", "exp-time": 1458396066}').digest('hex');
console.log( '1458396066' + '~'+ res);

The resulting hash I get is: 1458396066~d87d121117b46dc28ffec1117cd44cb114b32c1d7bfe5db30ebee7cb89221d3e

This is not the hash that I am expecting. I have implemented code in PHP and Java which seems to work fine.

PHP Code

<?php

 $videoId = "212zpS6bjN77eixPUMUEjR";
 $sharedSecret = "abc123";

function generateToken($videoId, $sharedSecret, $lifeTime)
{
$expiryTime = "1458396066";
$data = sprintf("{\"video-id\":\"%s\", \"exp-time\": %s}" , $videoId, "1458396066");
$hash = hash_hmac ( "sha256", $data , hex2bin($sharedSecret) );
$token = sprintf ("%s~%s","1458396066" , $hash);
return $token;
}

$token = generateToken($videoId, $sharedSecret, 5);
echo $token;
?>

JAVA Code

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.math.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class VMProToken {

public static void main(String[] args) {
    final String videoID = "212zpS6bjN77eixPUMUEjR";
    final String sharedSecret = "abc123";

    try {
        final String token = generateToken(videoID, sharedSecret);
        System.out.println(token);
    } catch (NoSuchAlgorithmException | InvalidKeyException e) {
        e.printStackTrace();
    }
}

private static String generateToken(String videoId, String sharedSecret)
        throws NoSuchAlgorithmException, InvalidKeyException {
    final String HASH_PATTERN = "{\"video-id\":\"%s\", \"exp-time\": %s}";
    final String HASH_ALGORITHM = "HmacSHA256";

    final String tokenCalcBase = String.format(HASH_PATTERN, videoId, 1458396066);
    System.out.println(tokenCalcBase);
    final Mac hmac = Mac.getInstance(HASH_ALGORITHM);
    final byte[] keyBytes = DatatypeConverter.parseHexBinary(sharedSecret);
    final SecretKeySpec secretKey = new SecretKeySpec(keyBytes, HASH_ALGORITHM);

    hmac.init(secretKey);
    final byte[] hmacBytes = hmac.doFinal(tokenCalcBase.getBytes());
    System.out.println(String.format("%064x", new BigInteger(1, hmacBytes)));
    final String hash = String.format("%064x", new BigInteger(1, hmacBytes));

    return 1458396066 + "~" + hash;
}
}

The above two codes result in the correct answer which is

1458396066~62dcbe0e20827245454280c51129a9f30d1122eaeafc5ce88f0fec527631f1b5

Can somebody please let me know what I'm doing wrong here?

1

1 Answers

1
votes

The key is processed as a hexadecimal encoded string in the PHP and Java code, but not in the NodeJS code. To do the same in the NodeJS code, replace 'abc123' with Buffer.from('abc123', 'hex') in the createHmac call.