我的任務是將一些現有的node.js代碼轉換爲Java。我認爲我很順利,但我現在有點困難。這些方法的輸出似乎不匹配。將HMAC-SHA1從node.js轉換爲Java
我在做什麼是基於查詢字符串創建一個SHA-1簽名。該查詢字符串包含一些與查詢相關的數據(與此問題無關)和API密鑰。
重要
- 的
api_secret
字符串中的node.js等同於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,但這是我的嘗試,我認爲做的是同一件事:
字節數組到十六進制的功能
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
我想不通,我錯在哪裏,我真的希望有人能擺脫光在這。