April 16, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Message Authentication: Unlocking the Secrets of the Java Cryptography Extensions, Page 4

  • December 1, 2008
  • By David Thurmond
  • Send Email »
  • More Articles »

The final step of the process is to write this data out to a file, sender_mac_data.txt, which the recipient can verify against his own authentication check.

Listing 4 shows how the recipient would recalculate the MAC on the decrypted message received by using the secret MAC key, and then would compare the calculated MAC to the sender's MAC to verify the integrity of the decrypted message.

Listing 4: VerifyMACFileExample.java

package com.dlt.developer.mac;

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

import javax.crypto.*;import java.security.Key;

import java.io.*;

public class VerifyMACFileExample {
   public static void main(String[] args) throws Exception {
      System.out.println("Calculating MAC and comparing to MAC
                          from sender...");

      BufferedInputStream in = new
         BufferedInputStream(new FileInputStream("mac_key.txt"));
      byte[] keyBytes = new byte[in.available()];
      in.read(keyBytes);
      in.close();
      SecretKeySpec skeySpec =
         new SecretKeySpec(keyBytes, "HmacMD5");

      Mac theMac = Mac.getInstance("HmacMD5");

      theMac.init(skeySpec);


      BufferedInputStream inData = new
         BufferedInputStream(new FileInputStream("plaintext.txt"));
      while (inData.available() > 0) {
         byte[] plaintextBytes = new byte[inData.available()];
         inData.read(plaintextBytes);
         theMac.update(plaintextBytes);
      }    // while
      inData.close();
      byte[] calculatedMacCode = theMac.doFinal();

      in = new BufferedInputStream(new FileInputStream(
         "sender_mac_data.txt"));
      byte[] senderMacCode = new byte[in.available()];
      in.read(senderMacCode);
      in.close();

      boolean macsAgree = true;
      if (calculatedMacCode.length != calculatedMacCode.length) {
         macsAgree = false;
         System.out.println("Sender MAC and calculated MAC length
                             are not the same.");
      } else {

         for (int i = 0; i < senderMacCode.length; i++) {
            if (senderMacCode[i] != calculatedMacCode[i]) {
               macsAgree = false;
               System.out.println("Sender MAC and calculated MAC
                                   are different. Message cannot
                                   be authenticated.");
break;

            }    // if
         }       // for i
      }          // if

      if (macsAgree) {
         System.out.println("Message authenticated successfully.");
      }    // if



      System.out.println("Done!");
   }    // main


}    // class VerifyMACFile

The output from the VerifyMACFileExample.java program is shown below:


Calculating MAC and comparing to MAC from sender...
Message authenticated successfully.
Done!

To verify the integrity of the sender's message, the recipient first reads the mac_key.txt file that contains the agreed-upon secret key value. Then, as in the sender's example, the Mac object is initialized with this secret key.

Next, the recipient loops through the decrypted plaintext.txt file and performs the same calls using the Mac object that the sender did earlier. Of course, in real life, the recipient would have received an encrypted file, and would have had to decrypt this file to get to this point in the process. I have omitted any encryption or decryption from these examples to avoid confusion, but one might well decrypt and authenticate within the same program for efficiency's sake.

After the final invocation of Mac.doFinal(), the recipient has a calculated MAC that should agree with the sender's. Now, the receiver reads the sender's sender_mac_data.txt file into another byte array for comparison.

At last, the time has come to verify the authenticity of the message. The code first checks to see whether the two arrays of bytes are the same length. If so, each array element is compared; if any do not match, authentication fails. Once both of these checks have passed, the message recipient can rest easy that the message the sender sent is the same as the one he has received.

Conclusion

Message authentication is necessary in situations where a message recipient must be guaranteed that the message he received was the one the sender sent. Here, you have learned how to create and verify MACs using the Java Cryptography Extensions. Using the techniques discussed here, you now have the tools to create a secure message exchange between a sender and a recipient, even when the message must pass through unsecured channels.

Download the Code

You can download code examples here.

References

About the Author

David Thurmond is a Sun Certified Developer with over fifteen years of software development experience. He has worked in the agriculture, construction equipment, financial, home improvement, and logistics industries.





Page 4 of 4



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel