Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Help required: How to generate an SHA1 MAC

843811Apr 7 2008 — edited May 25 2010
Hi

(Uh... I wasn't 100% where to post this, so I've posted it in two places - I hope that wasn't too naughty...)

I am attempting to generate an SHA1 MAC via code

The context is as follows:

I am submitting a wbxml payload to an SMS Gateway. Prior to the submission, I need to add a MAC as part of the required WSP (Wireless Session Protocol) Headers.

The actual process is very simple:

Take the message payload - i.e. a string of Hex characters. Use this as the *'data'*.
Take the 'user pin' - i.e. a string of decimal characters. Use this as the *'key'*.
Generate the MAC as a string of Hex characters. (In my case I use the Apache Commons for the Hex encoding.)

In order to test that my code works, I run the same test data through the HashCalc tool (http://www.slavasoft.com/hashcalc/index.htm).

The problem is, my code returns a different Hex string to that of HashCalc. Because my test data was taken from a documented sample, I can more or less confirm that the HashCalc tool is the correct output.

Can anyone see where I have gone wrong?

I have included my code and the results below.

Thanks
Pete

Java class:
import java.security.SignatureException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;

public class GenerateMac {
	private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";

	public static String calculateRFC2104HMAC(String data, String key) throws java.security.SignatureException {
	/**
	*@param data
	* The data to be signed. (The wbxml as a string of Hex digits.)
	*@param key
	* The signing key. (E.g. USERPIN of '1234')
	*/
		
		String result;
		
		try {

			// Get an hmac_sha1 key from the raw key bytes
			byte[] keyBytes = key.getBytes();			
			SecretKeySpec signingKey = new SecretKeySpec(keyBytes, HMAC_SHA1_ALGORITHM);
			 
			// Get an hmac_sha1 Mac instance and initialize with the signing key
			Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
			mac.init(signingKey);

			// Compute the hmac on input data bytes
			byte[] rawHmac = mac.doFinal(data.getBytes());
			
			// Convert raw bytes to Hex
			byte[] hexBytes = new Hex().encode(rawHmac);
			
			//  Covert array of Hex bytes to a String
			result = new String(hexBytes, "ISO-8859-1");
			System.out.println("MAC : " + result);

		} 
		catch (Exception e) {
			throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
			}
		return result;
		}
}
Input 'arguments':

Key:
1234
Data:
c54601c60001550187360603773500018722060342726f7773696e675f4750525300018707060353757065726d616e2053796e634d4c000187340603687474703a2f2f6d6574726f706f6c69732e636f6d3a383038302f736572766963652f73796e630001c65901873a06032e2f636f6e7461637473000187070603436f6e74616374732044420001872e0603746578742f782d7663617264000101c65901873a06032e2f63616c656e64617200018707060343616c656e6461722044420001872e0603746578742f782d7663616c656e646172000101c65701873106036e616d653400018732060370617373776f7264340001010101
Output:

My output:
dffe01657cc99b02394cb7b9708654558d63d4dd
Output from HashCalc: (Correct output)
49a4f8bac2a1987292a427faf7ad026c316f361f
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 22 2010
Added on Apr 7 2008
6 comments
674 views