基于哈希的消息身份验证代码 (MAC) 在接收端不匹配
Hash Based Message Authentication Codes (MAC) does not match at receiver end
我正在尝试创建一个基本的演示应用程序,其中 class 将生成一条以下列格式发送的消息
SignedMessage_using_HMAC.BASE64encoded_message
在接收端 (DecodeData.java) 首先我想比较消息是否使用正确的密钥签名,方法是解密已签名的消息,然后使用相同的密钥对消息签名,然后比较已签名的消息在接收端发送签名消息。
但是这些都不行。
当我尝试解码 Base64 编码的消息时,它没有给我正确的消息。
任何人都可以指导我这里有什么问题吗?
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class EncodeData {
public static void main(String[] args) throws Exception {
String myAppContext = "abc123def";
String consumerSecret = "959595";
String algorithm = "HMACSHA256";
byte[] encodedContext;
// Base64 encoded context;
encodedContext = new Base64(true).encode(myAppContext.getBytes());
System.out.print("Encoded Context : ");
System.out.println(encodedContext);
//Generate Signed context
SecretKey hmacKey = new SecretKeySpec(consumerSecret.getBytes(), algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(hmacKey);
byte[] digest = mac.doFinal(myAppContext.getBytes());
System.out.print("Created digest : ");
System.out.println(digest);
// Signed Based64 context and Base64 encoded context
String messageToSend = digest.toString() + "." + encodedContext.toString();
System.out.println(messageToSend);
}
}
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;
public class DecodeData {
public static void main(String[] args) throws Exception {
byte[] myAppContext;
String consumerSecret = "959595";
String algorithm = "HMACSHA256";
String messageRecieved = args[0];
byte[] singedDecodedContext;
String recievedDigest = messageRecieved.split("[.]", 2)[0];
String encodedContext = messageRecieved.split("[.]", 2)[1];
myAppContext = new Base64(true).decode(encodedContext);
System.out.print("Decrypted message : ");
System.out.println(myAppContext);
//Check if the message is sent by the correct sender by signing the context and matching with signed context
SecretKey hmacKey = new SecretKeySpec(consumerSecret.getBytes(), algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(hmacKey);
byte[] digest = mac.doFinal(myAppContext);
System.out.print("Created digest : ");
System.out.println(digest);
if (Arrays.equals(digest, recievedDigest.getBytes())) {
System.out.println("Message was not tempered and was sent by the correct sender");
} else {
System.out.println("Message was tempered or was not sent by the corrrect sender");
}
}
}
输出
EncodeData.java的输出
C:\Users\vivek.patel\Desktop\API\java\encoding>java -cp commons-codec-1.10.jar;.编码数据
编码上下文:[B@510bfe2c
创建摘要:[B@73f025cb
[B@73f025cb.[B@510bfe2c
DecodeData.java 的输出
C:\Users\vivek.patel\Desktop\API\java\encoding>java -cp commons-codec- 1.10.jar;.解码数据 [B@73f025cb.[B@510bfe2c
Decrypted message : [B@6726a408
Created digest : [B@7168bd8b
Message was tempered or was not sent by the correct sender
在评估您的代码之前,您实际上并没有比较这些值。
如果你这样打印:
System.out.print("Encoded Context : ");
System.out.println(encodedContext);
您只是打印数组的类型 ([B),然后是它的 hashCode。
使用编码字节初始化字符串:
System.out.println(new String(encodedContext, "UTF8"));
您还应该考虑使用显式字符集而不是默认字符集(取决于您的原始字符集)。
试一试并重新post你的结果。
我正在尝试创建一个基本的演示应用程序,其中 class 将生成一条以下列格式发送的消息 SignedMessage_using_HMAC.BASE64encoded_message
在接收端 (DecodeData.java) 首先我想比较消息是否使用正确的密钥签名,方法是解密已签名的消息,然后使用相同的密钥对消息签名,然后比较已签名的消息在接收端发送签名消息。 但是这些都不行。
当我尝试解码 Base64 编码的消息时,它没有给我正确的消息。
任何人都可以指导我这里有什么问题吗?
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class EncodeData {
public static void main(String[] args) throws Exception {
String myAppContext = "abc123def";
String consumerSecret = "959595";
String algorithm = "HMACSHA256";
byte[] encodedContext;
// Base64 encoded context;
encodedContext = new Base64(true).encode(myAppContext.getBytes());
System.out.print("Encoded Context : ");
System.out.println(encodedContext);
//Generate Signed context
SecretKey hmacKey = new SecretKeySpec(consumerSecret.getBytes(), algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(hmacKey);
byte[] digest = mac.doFinal(myAppContext.getBytes());
System.out.print("Created digest : ");
System.out.println(digest);
// Signed Based64 context and Base64 encoded context
String messageToSend = digest.toString() + "." + encodedContext.toString();
System.out.println(messageToSend);
}
}
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;
public class DecodeData {
public static void main(String[] args) throws Exception {
byte[] myAppContext;
String consumerSecret = "959595";
String algorithm = "HMACSHA256";
String messageRecieved = args[0];
byte[] singedDecodedContext;
String recievedDigest = messageRecieved.split("[.]", 2)[0];
String encodedContext = messageRecieved.split("[.]", 2)[1];
myAppContext = new Base64(true).decode(encodedContext);
System.out.print("Decrypted message : ");
System.out.println(myAppContext);
//Check if the message is sent by the correct sender by signing the context and matching with signed context
SecretKey hmacKey = new SecretKeySpec(consumerSecret.getBytes(), algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(hmacKey);
byte[] digest = mac.doFinal(myAppContext);
System.out.print("Created digest : ");
System.out.println(digest);
if (Arrays.equals(digest, recievedDigest.getBytes())) {
System.out.println("Message was not tempered and was sent by the correct sender");
} else {
System.out.println("Message was tempered or was not sent by the corrrect sender");
}
}
}
输出
EncodeData.java的输出 C:\Users\vivek.patel\Desktop\API\java\encoding>java -cp commons-codec-1.10.jar;.编码数据 编码上下文:[B@510bfe2c 创建摘要:[B@73f025cb [B@73f025cb.[B@510bfe2c
DecodeData.java 的输出 C:\Users\vivek.patel\Desktop\API\java\encoding>java -cp commons-codec- 1.10.jar;.解码数据 [B@73f025cb.[B@510bfe2c
Decrypted message : [B@6726a408
Created digest : [B@7168bd8b
Message was tempered or was not sent by the correct sender
在评估您的代码之前,您实际上并没有比较这些值。 如果你这样打印:
System.out.print("Encoded Context : ");
System.out.println(encodedContext);
您只是打印数组的类型 ([B),然后是它的 hashCode。 使用编码字节初始化字符串:
System.out.println(new String(encodedContext, "UTF8"));
您还应该考虑使用显式字符集而不是默认字符集(取决于您的原始字符集)。
试一试并重新post你的结果。