将HMAC-SHA1从node.js转换为Java [英] Converting HMAC-SHA1 from node.js to Java

查看:198
本文介绍了将HMAC-SHA1从node.js转换为Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的任务是将一些现有的node.js代码转换为Java。我觉得我很顺利,但现在我有点卡住了。方法的输出似乎不匹配。



我正在做的是根据查询字符串创建SHA-1签名。此查询字符串包含一些与查询相关的数据(与此问题无关)和API密钥。



重要




  • node.js中的 api_secret 字符串相当于 Config.API_SECRET in Java。

  • 示例查询字符串(在node.js和Java程序中它们相同):

    / events?festival = imaginate& pretty = 1& size = 100& from = 0& key = SOME_KEY



实际代码



SHA-1 hmac在nodejs中初始化如下:

  const hmac = crypto.createHmac('sha1',api_secret); 

SHA-1 mac在Java中初始化如下:

  final SecretKeySpec secretKeySpec = new SecretKeySpec(Config.API_SECRET.getBytes(UTF-8),HmacSHA1); 
final Mac hmac = Mac.getInstance(HmacSHA1);
hmac.init(secretKeySpec);

接下来,node.js程序更新hmac( query 参数如上所列):

  hmac.update(query,'ascii'); 

我在Java中复制的是这样的(查询参数等于node.js 查询参数):

  hmac.update(query.getBytes( US-ASCII)); 

最后,在node.js程序中将字节字符串转换为SHA-1哈希:

  const signature = hmac.digest('hex'); 

我找不到Java的确切翻译,但这是我的尝试,我认为关于同样的事情:



字节数组到十六进制函数

  public static String byteArrayToHex(byte [] a){
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b:a)
sb.append(String.format(%02x,b& 0xff));
返回sb.toString();
}

实际使用情况

  byte [] result = hmac.doFinal(); 
MessageDigest md = MessageDigest.getInstance(SHA-1);
String sha1Hash = byteArrayToHex(md.digest(result));

然而,这是我感到困惑的地方。 node.js程序返回此哈希值:
18cf4fce7bd6163c64d3b2ea8d935b0f16720fe3



但我的Java程序将此哈希值作为输出:
f65f8738cce89134dc73709e3353d94c83ccf1fb



我无法弄清楚我哪里出错了,我真的希望有人可以说清楚这一点。

解决方案

我想通了!



<事实证明我正在做一个不必要的步骤。



这一行:

  byte [] result = mac.doFinal (); 

已包含签名哈希。我需要将该字节数组转换为十六进制字符串,而不是该字节数组的摘要。



所以工作代码只是:

  byte [] result = mac.doFinal(); 
返回byteArrayToHex(result);


I have been tasked with converting some existing piece of node.js code to Java. I think I'm well on my way, but I'm kind of stuck right now. The output of the methods do not seem to match.

What I'm doing is creating a SHA-1 signature based on a query string. This query string contains some query-related data (not relevant for this question) and an API key.

Important

  • The api_secret string in node.js is equivalent to Config.API_SECRET in Java.
  • Example query string (these are equal in the node.js and Java program):
    /events?festival=imaginate&pretty=1&size=100&from=0&key=SOME_KEY

Actual code

The SHA-1 hmac is initialized as follows in nodejs:

const hmac = crypto.createHmac('sha1', api_secret);

The SHA-1 mac is initialized as follows in Java:

final SecretKeySpec secretKeySpec = new SecretKeySpec(Config.API_SECRET.getBytes("UTF-8"), "HmacSHA1");
final Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(secretKeySpec);

Next, the node.js program updates the hmac as such (query parameter is as listed above):

hmac.update(query, 'ascii');

Which I replicated in Java like this (query parameter is equal to the node.js query parameter):

hmac.update(query.getBytes("US-ASCII"));

Finally, the byte string is converted to a SHA-1 hash as such in the node.js program:

const signature = hmac.digest('hex');

I couldn't find an exact translation to Java, but this was my attempt, which I think does about the same thing:

Byte array to hex function

public static String byteArrayToHex(byte[] a) {
    StringBuilder sb = new StringBuilder(a.length * 2);
    for(byte b: a)
        sb.append(String.format("%02x", b & 0xff));
    return sb.toString();
}

Actual usage

byte[] result = hmac.doFinal();
MessageDigest md = MessageDigest.getInstance("SHA-1");
String sha1Hash = byteArrayToHex(md.digest(result));

However, this is where I get confused. The node.js program returns this hash: 18cf4fce7bd6163c64d3b2ea8d935b0f16720fe3

But my Java program gives this hash as output: f65f8738cce89134dc73709e3353d94c83ccf1fb

I can't figure out where I went wrong and I really hope someone could shed a light on this.

解决方案

I figured it out!

Turns out I was doing one unnecessary step.

This line:

byte[] result = mac.doFinal();

Already contained the signature hash. I needed to convert that byte array to a hex string, not the digest of that byte array.

So the working code was simply:

byte[] result = mac.doFinal();
return byteArrayToHex(result);

这篇关于将HMAC-SHA1从node.js转换为Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆