我正在尝试将我的节点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
你能帮我指出我在这里犯的错误。为什么签名不匹配?
答案 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