0

I have a encryption function in Java that I am trying to convert to Javascript and for some reason the hash generated in the end is not the same.

I am using crypto for javascript and Mac for Java.

Javascript:

    const time = 0,0,0,0,0,8,21,60;
    const signKey = 20,54,50,82;

    const hash = crypto
       .createHmac('sha1', new Buffer(signKey, 'base64'))
       .update(new Buffer(time))
       .digest('hex');

    console.log(`hash ${hash}`);

Java:

    byte[] time = 0,0,0,0,0,8,21,60;
    byte[] signKey = 20,54,50,82;
     SecretKeySpec signKey = new SecretKeySpec(signKey, "HmacSHA1");

    Mac mac;
    mac = Mac.getInstance("HmacSHA1");
    mac.init(signKey);
    byte[] hash = mac.doFinal(time);

Javascript - Output:

hash = 52,56,48

Java - Output: hash = [-47, 30, -1]

I think I am missing to convert something in Javascript, but as I am not familiar with cryptos, I am not sure.

Thank you !

3
  • 1
    const time = 0,0,0,0,0,3,58,60; throws a syntax error in here, are you using a framework that allows this? From what i know, this should be const time = [0,0,0,0,0,3,58,60]; Commented Apr 5, 2018 at 9:29
  • For debugging byte arrays I'd suggest you print output byte arrays as hexadecimals. Commented Apr 5, 2018 at 16:01
  • The Java Script is already hexadecimal encoded. But then you show those hexadecimal characters as decimal values, so you encode them twice before displaying them. Commented Apr 5, 2018 at 16:10

2 Answers 2

1

As I can see in JS you are treating signKey as base64 encoded string and in Java -- as byte array. So removing 'base64' from JS code should help.

Sign up to request clarification or add additional context in comments.

1 Comment

The base 64 input is not base 64 encoded by the way; if you convert it to ASCII you get "04:E6:76:39:6E:99automation". Meaning that even if it is handled as a key, it would have about 48 bits of security at the very maximum, which is not enough. This in support of this answer.
1

Hi I managed to find the solution, so yes indeed one of the things was remove the base64 and the Buffers from the JS code and also I should digest without converting it to hexadecimal.

Sincer I removed the Buffer, I had to convert both of the Arrays into TypedArrays since crypto just accepts, Buffers, TypedArrays, String and DataViews.

After this I should convert the hash into a Unit32Array and this should be the same hash from the Java code

So, in the end the code is:

         const timeInBytes = 0,0,0,0,0,8,21,60;
         const combinedSecret = 20,54,50,82;

         const signKey = Uint8Array.from(combinedSecret);
         const time = Uint8Array.from(timeInBytes);

         const hash = crypto
            .createHmac('sha1', signKey)
            .update(time)
            .digest();

        const encodedArray = Uint32Array.from(hash);

Thank you guys !

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.