Java Hmac-Sha1 hexdigest 不同于 Nodejs
Java Hmac-Sha1 hexdigest different to Nodejs
我一直在努力使基本的 HMAC-SHA1 请求签名方法起作用。
服务端使用NodeJS验证签名。为了检查我应该得到什么,我将下面的脚本写到 运行 本地(我已经用 cURL 测试过以确保它生成正确的签名)。
const body = JSON.stringify(require('./json-events/test-event.json'));
const crypto = require('crypto');
const digest = crypto.createHmac('sha1', secretKey)
.update(body, 'utf8')
.digest('hex');
console.log(digest);
打印出 70c244c06513c882bb8704c2d887a95a08d77f3a
客户的签名代码是;
String xSignature = null;
final char[] hexArray = "0123456789abcdef".toCharArray();
try {
SecretKeySpec key = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(key);
byte[] digest = mac.doFinal(body.getBytes("UTF-8"));
char[] hexChars = new char[digest.length * 2];
for (int j = 0; j < digest.length; ++j) {
int v = digest[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
xSignature = new String(hexChars);
} catch (Exception e) {
System.out.println(e.getMessage());
}
其中,当打印出 xSignature
时,它给出 5f855052675f135da151d6fa844a7678ede90afc
。
为了尝试调试它,我使用了一个快速 python3 脚本来检查哪个不正确。
import hashlib
import hmac
import json
from collections import OrderedDict
body = json.dumps(json.load(open("json-events/test-event.json"),
object_pairs_hook=OrderedDict), indent=2).encode("utf-8")
sig = hmac.new(secret_key, msg=body, digestmod=hashlib.sha1).hexdigest()
print(sig)
Returns5f855052675f135da151d6fa844a7678ede90afc
,与Java方法相同
虽然我到处查看,但似乎 NodeJS 代码是 100% 正确的。所以我猜我的 Java 和 Python 代码中存在一个共同的缺陷。
如有任何见解,我们将不胜感激。
这是我浏览过的其他一些网页;
Python HMAC-SHA1 vs Java HMAC-SHA1 different results
Preparing a string for HMAC
NodeJS Crypto Hmac class documentation
UPDATE:使用更简单的字符串 "asdfghjkl" 而不是复杂的 JSON 字符串,生成相同的签名。因此,在将 Java/Python 与 NodeJS 进行比较时,似乎有一些不可见的字符正在更改摘要。
我找到了问题的解决方案(忘记了 post 此处的答案)。当字典的键值对顺序不同时,签名也不同。这么简单的疏忽。
所以;
{
"key1": "Value1",
"key2": "Value2"
}
将生成不同的摘要字符串;
{
"key2": "Value2",
"key1": "Value1"
}
因此,在计算两种语言之间的 HMAC-SHA1 时,请确保您的键值的排序方式完全相同!
我一直在努力使基本的 HMAC-SHA1 请求签名方法起作用。
服务端使用NodeJS验证签名。为了检查我应该得到什么,我将下面的脚本写到 运行 本地(我已经用 cURL 测试过以确保它生成正确的签名)。
const body = JSON.stringify(require('./json-events/test-event.json'));
const crypto = require('crypto');
const digest = crypto.createHmac('sha1', secretKey)
.update(body, 'utf8')
.digest('hex');
console.log(digest);
打印出 70c244c06513c882bb8704c2d887a95a08d77f3a
客户的签名代码是;
String xSignature = null;
final char[] hexArray = "0123456789abcdef".toCharArray();
try {
SecretKeySpec key = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(key);
byte[] digest = mac.doFinal(body.getBytes("UTF-8"));
char[] hexChars = new char[digest.length * 2];
for (int j = 0; j < digest.length; ++j) {
int v = digest[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
xSignature = new String(hexChars);
} catch (Exception e) {
System.out.println(e.getMessage());
}
其中,当打印出 xSignature
时,它给出 5f855052675f135da151d6fa844a7678ede90afc
。
为了尝试调试它,我使用了一个快速 python3 脚本来检查哪个不正确。
import hashlib
import hmac
import json
from collections import OrderedDict
body = json.dumps(json.load(open("json-events/test-event.json"),
object_pairs_hook=OrderedDict), indent=2).encode("utf-8")
sig = hmac.new(secret_key, msg=body, digestmod=hashlib.sha1).hexdigest()
print(sig)
Returns5f855052675f135da151d6fa844a7678ede90afc
,与Java方法相同
虽然我到处查看,但似乎 NodeJS 代码是 100% 正确的。所以我猜我的 Java 和 Python 代码中存在一个共同的缺陷。
如有任何见解,我们将不胜感激。
这是我浏览过的其他一些网页;
Python HMAC-SHA1 vs Java HMAC-SHA1 different results
Preparing a string for HMAC
NodeJS Crypto Hmac class documentation
UPDATE:使用更简单的字符串 "asdfghjkl" 而不是复杂的 JSON 字符串,生成相同的签名。因此,在将 Java/Python 与 NodeJS 进行比较时,似乎有一些不可见的字符正在更改摘要。
我找到了问题的解决方案(忘记了 post 此处的答案)。当字典的键值对顺序不同时,签名也不同。这么简单的疏忽。
所以;
{
"key1": "Value1",
"key2": "Value2"
}
将生成不同的摘要字符串;
{
"key2": "Value2",
"key1": "Value1"
}
因此,在计算两种语言之间的 HMAC-SHA1 时,请确保您的键值的排序方式完全相同!