March 5, 2021
Hot Topics:

Message Authentication: Unlocking the Secrets of the Java Cryptography Extensions

  • By David Thurmond
  • Send Email »
  • More Articles »

In this example, two very different plaintexts give the same cryptographic hash value. Of course, real-world cryptographic hash functions are much more robust. It is much more difficult to generate the same hash code from two different plaintexts as I have done above. However, this simple example demonstrates the fatal flaw in using a cryptographic hash function by itself; the hash code the recipient gets is only as secure as the complexity of the hash function one uses.

Message authentication extends the concept of using a cryptographic hash function, but adds yet another layer of security by basing the hash code itself on a predetermined secret key value. Thus, the sender and recipient of the hash code must agree on the secret key ahead of time. Changing the secret key value completely changes the hash code that would be returned by using the exact same authentication algorithm, so a third party is less likely to be able to figure out what the hash code is, or to be able to produce a hash code of his own to go with an intercepted and modified message.

A Simple Message Authentication Example

Now, I will demonstrate how to perform the same task as in my earlier example using true message authentication. Consider the full listing of SimpleMacExample.java shown in Listing 2.

Listing 2: SimpleMacExample.java

package com.dlt.developer.mac;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.crypto.*;

public class SimpleMacExample {

   public static String getPlainText() {
      System.out.print("Enter plaintext:");
      String plaintext = "";
      BufferedReader br =
         new BufferedReader(new InputStreamReader(System.in));
      try {
         plaintext = br.readLine();
      } catch (IOException ioe) {
         System.out.println("IO error trying to read plaintext!");
      }    // catch
      return plaintext;
   }       // getPlainText()

   public static void main(String[] args) throws Exception {
      System.out.println("This program generates a message
         authentication code for the plaintext you enter.");
      String plaintextString = getPlainText();
      byte[] plaintext = plaintextString.getBytes();

      KeyGenerator keygen = KeyGenerator.getInstance("HmacMD5");
      SecretKey sKey = keygen.generateKey();

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

      byte[] theMacCode = theMac.doFinal(plaintext);

      System.out.print("The MAC for the plaintext \'" +
                       plaintextString + "\' is ");
      for (int i = 0; i < theMacCode.length; i++) {
      if (i != theMacCode.length - 1) {
      }    // if
   }       // for i
   }       // main

}          // class SimpleMacExample

The output generated from running this program is shown below:

This program generates a message authentication code for the
   plaintext you enter.
Enter plaintext:Attack at dawn!
The MAC for the plaintext 'Attack at dawn!' is -5,-40,-58,-34,43,

This program generates a message authentication code for the
   plaintext you enter.
Enter plaintext:Surrender.
The MAC for the plaintext 'Surrender.' is -96,-20,97,73,11,-88,

As you can see from the output, the problem demonstrated in the SimpleCryptoHash.java example has been solved. These two plaintexts do not generate the same series of bytes when the MD5 message authentication scheme is used. Before running this example, you will need to install and configure the Java Cryptography Extension and any third-party libraries you might wish to use, as described in my article "Unlocking the Secrets of Java Cryptography Extensions: The Basics."

Now, examine each step of the process of generating the message authentication code.

First, as in the earlier example, the plaintext is read from the command line. Next, a secret key is generated, which is necessary for generating the MAC:

KeyGenerator keygen = KeyGenerator.getInstance("HmacMD5");
SecretKey sKey = keygen.generateKey();

Note that only particular algorithms are suitable for message authentication. Commonly used algorithms are HmacMD5 and HmacSHA-1. Using an inappropriate algorithm will result in an exception being thrown.

Page 2 of 4

This article was originally published on December 1, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date