使用 HmacSHA256 散列 returns 意外结果
Hashing with HmacSHA256 returns unexpected result
我需要使用 SHA-256 算法对 MAC 的消息进行签名。我有生成 MAC 的代码,但另一端的验证失败。
我被告知我计算的值是错误的。
这是我的代码
public static byte[] calculateMAC(byte[] _aiOutBufferForMacCalculation, String key) {
try{
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] mac_data=sha256_HMAC.doFinal(_aiOutBufferForMacCalculation);
String result = "";
for (final byte element : mac_data)
{
result += Integer.toString((element & 0xff) + 0x100, 16).substring(1);
}
System.out.println("Result:[" + result + "]");
return mac_data;
} catch (Exception _exception) {
_exception.printStackTrace();
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public static void main(String[] args) {
String key = "7F6D7A688019DC4CA83883F2459E6B389BE99BB63B622A97";
String cadena = "1800990000014303181112190600048430303030303134370029030003483032001148324830303030303135320008143919751D5EB97C";
byte[] data_for_mac = hexStringToByteArray(cadena);
System.out.println(new String(data_for_mac));
byte[]mac = calculateMAC(data_for_mac,key);
}
}
我看到的打印结果是:
0e01a8a96b30ae0a918865d1cef898ea4f96e18680fa9aae4c5d9902090c2f81
但期望值是:
7684024da7fe89029965ac037a1ec94b21479c91cd8495e726fec924e84b0773
我使用了几个在线工具,这些工具允许我输入一个十六进制字符串作为 inputo 来生成散列。结果和预想的一样,确认是我的有问题
我不知道我可能做错了什么,有人可以帮忙吗?
谢谢
根据您的 main
函数参数,我预计该键也是十六进制字符串。所以你也需要为它调用 hexStringToByteArray
。 getBytes()
方法只是 return 字节,它不会从十六进制字符串转换。
将 calculateMAC
函数更改为如下内容:
public static byte[] calculateMAC(byte[] _aiOutBufferForMacCalculation, byte[] key) {
try{
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256");
...
}
而你main
喜欢这样:
public static void main(String[] args) {
String key = "7F6D7A688019DC4CA83883F2459E6B389BE99BB63B622A97";
String cadena = "1800990000014303181112190600048430303030303134370029030003483032001148324830303030303135320008143919751D5EB97C";
byte[] data_for_mac = hexStringToByteArray(cadena);
byte[] mac_key = hexStringToByteArray(key);
// System.out.println(new String(data_for_mac)); <-- what is this????
byte[] mac = calculateMAC(data_for_mac,mac_key);
}
我进行了测试,通过这 2 个小的更改,您会得到预期的结果。
顺便说一句,我认为您肯定没有在该示例代码中发布所有重要密钥,而只是使用了一个虚拟密钥。 :D
我需要使用 SHA-256 算法对 MAC 的消息进行签名。我有生成 MAC 的代码,但另一端的验证失败。 我被告知我计算的值是错误的。
这是我的代码
public static byte[] calculateMAC(byte[] _aiOutBufferForMacCalculation, String key) {
try{
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] mac_data=sha256_HMAC.doFinal(_aiOutBufferForMacCalculation);
String result = "";
for (final byte element : mac_data)
{
result += Integer.toString((element & 0xff) + 0x100, 16).substring(1);
}
System.out.println("Result:[" + result + "]");
return mac_data;
} catch (Exception _exception) {
_exception.printStackTrace();
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public static void main(String[] args) {
String key = "7F6D7A688019DC4CA83883F2459E6B389BE99BB63B622A97";
String cadena = "1800990000014303181112190600048430303030303134370029030003483032001148324830303030303135320008143919751D5EB97C";
byte[] data_for_mac = hexStringToByteArray(cadena);
System.out.println(new String(data_for_mac));
byte[]mac = calculateMAC(data_for_mac,key);
}
}
我看到的打印结果是: 0e01a8a96b30ae0a918865d1cef898ea4f96e18680fa9aae4c5d9902090c2f81
但期望值是: 7684024da7fe89029965ac037a1ec94b21479c91cd8495e726fec924e84b0773
我使用了几个在线工具,这些工具允许我输入一个十六进制字符串作为 inputo 来生成散列。结果和预想的一样,确认是我的有问题
我不知道我可能做错了什么,有人可以帮忙吗? 谢谢
根据您的 main
函数参数,我预计该键也是十六进制字符串。所以你也需要为它调用 hexStringToByteArray
。 getBytes()
方法只是 return 字节,它不会从十六进制字符串转换。
将 calculateMAC
函数更改为如下内容:
public static byte[] calculateMAC(byte[] _aiOutBufferForMacCalculation, byte[] key) {
try{
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256");
...
}
而你main
喜欢这样:
public static void main(String[] args) {
String key = "7F6D7A688019DC4CA83883F2459E6B389BE99BB63B622A97";
String cadena = "1800990000014303181112190600048430303030303134370029030003483032001148324830303030303135320008143919751D5EB97C";
byte[] data_for_mac = hexStringToByteArray(cadena);
byte[] mac_key = hexStringToByteArray(key);
// System.out.println(new String(data_for_mac)); <-- what is this????
byte[] mac = calculateMAC(data_for_mac,mac_key);
}
我进行了测试,通过这 2 个小的更改,您会得到预期的结果。
顺便说一句,我认为您肯定没有在该示例代码中发布所有重要密钥,而只是使用了一个虚拟密钥。 :D