在JavaScript中计算HMAC:从Java转换

时间:2018-04-05 09:22:47

标签: javascript arrays cryptography

我在Java中有一个加密函数,我试图将其转换为Javascript,并且由于某种原因,最终生成的哈希值不一样。

我正在使用crypto用于javascript和Mac用于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}`);

爪哇

    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 - 输出

hash = 52,56,48

Java - 输出hash = [-47, 30, -1]

我想我错过了用Javascript转换的东西,但由于我不熟悉密码,我不确定。

谢谢!

2 个答案:

答案 0 :(得分:1)

正如我在JS中看到的那样,你将signKey视为base64编码的字符串,而在Java中则视为字节数组。 因此,从JS代码中删除“base64”应该会有所帮助。

答案 1 :(得分:1)

您好我找到了解决方案,所以确实其中一件事是从JS代码中删除了base64和Buffers,我也应该在不将其转换为十六进制的情况下进行消化。

自从我删除了Buffer之后,我不得不将两个Arrays转换为TypedArrays,因为crypto只接受,Buffers,TypedArrays,String和DataViews。

在此之后,我应该将哈希转换为Unit32Array,这应该是来自Java代码的相同哈希

所以,最后代码是:

         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);

谢谢你们!