在Java中的HMAC SHA1签名
我想与TransUnion Web服务接口,我需要提供一个HMAC-SHA1签名来访问它。在Java中的HMAC SHA1签名
这个例子是环联文档中:
安全输入的SampleIntegrationOwner2008‐11‐18T19:14:40.293Z
键xBy/2CLudnBJOxOtDhDRnsDYq9HTuDVr2uCs3FMzoxXEA/Od9tOuwSC70+mIfpjeG68ZGm/PrxFf/s/CzwxF4Q==
创建的/UhwvT/kY9HxiXaOjpIc/BarBkc=
输出。
鉴于数据和密钥,我无法在Java中获得相同的结果。我已经尝试了几种在线计算器,并且他们都没有返回这个结果。他们的文档中的示例是不正确的,还是我没有正确处理这些字符串?
这里是我目前正与代码:
public static String calcShaHash (String data, String key) {
String HMAC_SHA1_ALGORITHM = "HmacSHA1";
String result = null;
try {
Key signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data.getBytes());
result = Base64.encodeBase64String(rawHmac);
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
这里是我的单元测试代码:
@Test
public void testCalcShaHash() {
String data = "SampleIntegrationOwner2008-11-18T19:14:40.293Z";
String key = "xBy/2CLudnBJOxOtDhDRnsDYq9HTuDVr2uCs3FMzoxXEA/Od9tOuwSC70+mIfpjeG68ZGm/PrxFf/s/CzwxF4Q==";
String result = Utils.calcShaHash(data, key);
assertEquals(result, "/UhwvT/kY9HxiXaOjpIc/BarBkc=");
}
一件事我注意到的是,连字符是不正常的连字符。如果您复制并粘贴它们,它们不在ASCII字符集中。我可以肯定地说哈希长度显示正确。有趣的是,即使在输入正确的连字符后,我也无法让你的代码产生正确的答案。但是不管。它解决了这个问题。好哇!
@Shane你可以在这里复制你最新的SSCE吗?我复制了你的原始代码,用适当的连字符更新它,但它仍然失败。我认为还有另一个区别,我们还没有确定我想保留后代。 –
这看起来像一个Base64编码的关键。所以我认为你需要对它做一个base64解码,然后把它传递给HMAC。像这样的东西(只是为了说明我没有测试过,任何错误都为读者的练习):
public String getHmacMD5(String privateKey, String input) throws Exception{
String algorithm = "HmacSHA1";
byte[] keyBytes = Base64.decode(privateKey);
Key key = new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(key);
return Base64.encode(mac.doFinal(input.getBytes()));
}
我试过了,但还是没有得到正确的答案。见上面的代码示例。 – Shane
@chubb是否可以使用用于加密的密钥来解密值? –
否HMAC是使用公钥/私钥对验证是否使用特定密钥生成哈希的单向哈希。在常规的单向散列函数(SHA1,MD5,SHA256等)中,没有涉及任何秘密密钥,因此知道算法的任何人都可以创建散列。 HMAC允许您确保只有持有特定密钥的人员/系统才会生成此散列,而不是其他人。 – chubbsondubs
从文档的更大的摘录可能会有所帮助。我注意到的一件事是连字符不是正常的连字符。如果您复制并粘贴它们,它们不在ASCII字符集中。我可以肯定地说哈希长度显示正确。 –
@John Watts - 你对破折号的评论是正确的。我复制并粘贴来自Word文档的文本。破折号不是标准的ASCII字符。通过使用正常破折号,结果是正确的,无需解码密钥。请添加您的评论作为答案。 – Shane