java中的HMAC签名

时间:2017-11-30 08:39:48

标签: java node.js hmac hmacsha1

我正在尝试将我的节点js POST调用转换为Java。在这样做时,我想将HMAC签名生成的逻辑更改为java方法。但签名似乎在节点js与java中不匹配。我将在下面粘贴我的节点js和java代码供您参考:

const crypto = require('crypto');
const CONTENT_TYPE = 'Content-Type';
const APPLICATION_JSON_UTF8 = 'application/json; charset=utf-8';
const SIGNATURE = 'X-Hub-Signature';


const botConfig = {
    webhookURL: 'WEBHOOK_URL',
    secretKey: 'hP6pFhyqazD3vCuw5wjzGwicqF3nPq1H'
};


function buildSignatureHeader(buf, secret) {
    return 'sha256=' + buildSignature(buf, secret);
}

function buildSignature(buf, secret) {
    const hmac = crypto.createHmac('sha256', Buffer.from(secret, 'utf8'));
    hmac.update(buf);
    return hmac.digest('hex');
}

app.get('/', function (req, res) {
    const recvMessage =  {
                        "userId":"USERID",
                        "messagePayload": {
                            "type":"agent",
                            "text": "hi",
                            "channelName":"ENDPOINT"
                        },
                        "profile": {"firstName": 'SOMEUSER'}
                      };




console.log("Going to Call");
 const data = Buffer.from(JSON.stringify(recvMessage), 'utf8');
 const headers = {};
    headers[CONTENT_TYPE] = APPLICATION_JSON_UTF8;
    headers[SIGNATURE]    = buildSignatureHeader(data, botConfig.secretKey);
    var interactive = false;
    var oauth=false;
    console.log('signature:'+  buildSignatureHeader(JSON.stringify(recvMessage), botConfig.secretKey));

在Java中,我的证书生成代码如下:

public class HmacSha1Signature {
  /*  public HmacSha1Signature() {
        super();
    }
*/
  private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";

          private static String toHexString(byte[] bytes) {
                  Formatter formatter = new Formatter();

                  for (byte b : bytes) {
                          formatter.format("%02x", b);
                  }

                  return formatter.toString();
          }

          public static String calculateRFC2104HMAC(String data, String key)
                  throws SignatureException, NoSuchAlgorithmException, InvalidKeyException
          {
               SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA256");
              Mac mac = Mac.getInstance("HmacSHA256");
              mac.init(signingKey);

              return toHexString(mac.doFinal(data.getBytes()));
          }

          public static void main(String[] args) throws Exception {

                  String data= "{\n" + 
                  "                        \"userId\":\"USERID\",\n" + 
                  "                        \"messagePayload\": {\n" + 
                  "                            \"type\":\"agent\",\n" + 
                  "                            \"text\": \"hi\",\n" + 
                  "                            \"channelName\":\"CHANNEL\"\n" + 
                  "                        },\n" + 
                  "                        \"profile\": {\"firstName\": 'SOMEUSER'}\n" + 
                  "                      }";
                  String hmac = calculateRFC2104HMAC(data, "hP6pFhyqazD3vCuw5wjzGwicqF3nPq1H");

                  System.out.println(hmac);

          }
} 

在NODE JS中,我的签名如下:

2176fd6b050b536f65ac146fb8471f1472098a7cc5e17bc61f85cf82e06e45d7

在java中,它是:

2a899031182deda92c4cf97dd84c246ff65371acb9c41c04c360e1ab512e6038

你能帮我指出我在这里犯的错误。为什么签名不匹配?

1 个答案:

答案 0 :(得分:0)

对我来说,计算在Java中起作用的HMAC签名的唯一方法是:

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.binary.Hex;

final String HMAC_SHA512 = "HmacSHA512";
final String CHARSET = "ISO-8859-1";
final String HMAC_KEY = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF01...";

String hmacFootprint = null;
Mac mac = Mac.getInstance(HMAC_SHA512);
mac.init(new SecretKeySpec(DatatypeConverter.parseHexBinary(HMAC_KEY), mac.getAlgorithm()));
final byte[] macData = mac.doFinal(requestParameters.toString().getBytes());
byte[] hex = new Hex().encode(macData);
hmacFootprint = new String(hex, CHARSET).toUpperCase();

希望有帮助。

感谢您的回答:java hmac/sha512 generation