将HMAC-SHA1从node.js转换为Java
我的任务是将一些现有的node.js代码转换为Java。 我觉得我很顺利,但现在我有点卡住了。 方法的输出似乎不匹配。
我正在做的是基于查询字符串创建SHA-1签名。 此查询字符串包含一些与查询相关的数据(与此问题无关)和API密钥。
重要
- node.js中的
api_secret
字符串等同于Java中的Config.API_SECRET
。 - 示例查询字符串(在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中复制了这个( query
参数等于node.js query
参数):
hmac.update(query.getBytes("US-ASCII"));
最后,在node.js程序中将字节字符串转换为SHA-1哈希:
const signature = hmac.digest('hex');
我找不到Java的确切翻译,但这是我的尝试,我认为这是关于同样的事情:
字节数组为hex函数
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(); }
实际用途
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();
已经包含签名哈希。 我需要将该字节数组转换为hex字符串,而不是该字节数组的摘要。
所以工作代码很简单:
byte[] result = mac.doFinal(); return byteArrayToHex(result);
- 手动validationXML签名
- Java BouncyCastle ECC密钥和自签名证书
- 在BouncyCastle上使用数字签名算法(ECDSA)实现的椭圆曲线
- java.lang.IllegalArgumentException:string curve25519 not a OID bouncycastle 1.52
- 如何从EC公钥字节中获取PublicKey对象?
- MessageDigest.getInstance(“SHA”)返回什么特定的哈希算法?
- 使用此椭圆曲线点乘法计算的点不在曲线上,并且此类带来算术exception
- 如何使用java PKCS#12密钥库中的证书来加密和解密文件?
- CryptoAPI C ++使用AES与Java互操作