Java Hmac-Sha1 hexdigest与Nodejs不同

时间:2017-03-24 01:03:52

标签: java node.js python-3.x hmacsha1

我一直在尝试使用基本的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)

返回5f855052675f135da151d6fa844a7678ede90afc,它与Java方法相同。

我看到的每个地方,似乎NodeJS代码是100%正确的。所以我猜我的Java和Python代码存在一个共同的缺陷。

非常感谢任何见解。

以下是我看过的其他一些网页;

Python HMAC-SHA1 vs Java HMAC-SHA1 different results

Converting HMAC-SHA1 from node.js to Java

Preparing a string for HMAC

NodeJS Crypto Hmac class documentation

UPDATE :使用更简单的字符串“asdfghjkl”而不是复杂的JSON字符串,生成相同的签名。因此,在将Java / Python与NodeJS进行比较时,似乎有一些不可见的字符正在改变摘要。

1 个答案:

答案 0 :(得分:0)

找到问题的解决方案(忘了在这里发布答案)。当字典的键值对的顺序不同时,签名是不同的。这么简单的疏忽。

因此;

{
    "key1": "Value1",
    "key2": "Value2"
}

将生成不同的摘要字符串;

{
    "key2": "Value2",
    "key1": "Value1"
}

因此,在计算两种语言之间的HMAC-SHA1时,请确保您的键值的排序方式完全相同!