1

I am trying to create a basic demo application where one class will generate a message to be sent in the following format SignedMessage_using_HMAC.BASE64encoded_message

At the receiving end (DecodeData.java) first I wan to compare if the message was signed using the right key by decrypting the signed message and then signing the message with the same key and then compare the signed message at the receiver end the signed message sent. But these do not work.

When I try to decode the Base64 encoded message it does not give me the correct message.

Can anyone please guide me what's wrong here?

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");
    }   
}   
}

Output

Output of EncodeData.java C:\Users\vivek.patel\Desktop\API\java\encoding>java -cp commons-codec-1.10.jar;. EncodeData Encoded Context : [B@510bfe2c Created digest : [B@73f025cb [B@73f025cb.[B@510bfe2c

Output of DecodeData.java C:\Users\vivek.patel\Desktop\API\java\encoding>java -cp commons-codec- 1.10.jar;. DecodeData [B@73f025cb.[B@510bfe2c

Decrypted message : [B@6726a408
Created digest : [B@7168bd8b
Message was tempered or was not sent by the correct sender
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
vpate
  • 13
  • 3
  • possible duplicate of [How do I print my Java object without getting "SomeType@2f92e0f4"?](http://stackoverflow.com/questions/29140402/how-do-i-print-my-java-object-without-getting-sometype2f92e0f4) – Artjom B. Apr 01 '15 at 10:16

1 Answers1

0

Before evaluate your code, you aren't actually comparing the values. If you print like this:

System.out.print("Encoded Context : ");
System.out.println(encodedContext);

You are just printting the type of the array ([B) followed by its hashCode. Initialize a String with the encoded bytes:

System.out.println(new String(encodedContext, "UTF8"));

You should also consider using an explicit charset instead of the default one (depending on your origin charset).

Try it and re-post your results.

exoddus
  • 2,230
  • 17
  • 27
  • Hi exoddus, Thanks for you comment, I have updated the code and the output now is---------- Output of EncodeData.java C:\Users\vivek.patel\Desktop\API\java\encoding>java -cp commons-codec-1.10.jar;. EncodeData Encoded Context : YWJjMTIzZGVm Created digest : [B@73f025cb [B@73f025cb.YWJjMTIzZGVm Output of DecodeData.java C:\Users\vivek.patel\Desktop\API\java\encoding>java -cp commons-codec-1.10.jar;. DecodeData [B@73f025cb.YWJjMTIzZGVm Decrypted message : abc123def Created digest : [B@6da13047 Message was tempered or was not sent by the corrrect sender ------------- – vpate Apr 01 '15 at 07:20
  • how can I post my code again? I don't have option to post the code. – vpate Apr 01 '15 at 07:20
  • you should print ALL the byte[] you want to compare: System.out.println(new String(digest, "UTF8")), System.out.println(new String(myAppContext, "UTF8"))... Is "abc123def" your text input? According to your output seems that description is working ok, isn't it? You can't EDIT your original post due to low reputation, must add comments – exoddus Apr 01 '15 at 07:54
  • Hi exoddus, You are right, I was printing the object hash code instead of actually printing the string value. I have replaced the code at other places also and now the match works fine. – vpate Apr 01 '15 at 09:55
  • Maybe you are right, but comments with code (like above comments) are awkward to read... – exoddus Apr 01 '15 at 09:56