Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HMAC SHA1 Signature in Java

Tags:

java

sha

hmacsha1

I am trying to interface with a TransUnion web service and I need to provide a HMAC-SHA1 signature to access it.

This example is in the TransUnion documentation:
Input of SampleIntegrationOwner2008‐11‐18T19:14:40.293Z with security key xBy/2CLudnBJOxOtDhDRnsDYq9HTuDVr2uCs3FMzoxXEA/Od9tOuwSC70+mIfpjeG68ZGm/PrxFf/s/CzwxF4Q== creates output of /UhwvT/kY9HxiXaOjpIc/BarBkc=.

Given that data and key, I cannot get this same result in Java. I have tried several online calculators, and none of them return this result either. Is the example in their documentation incorrect, or am I just not handling these strings correctly?

Here is the code I am currently working with:

public static String calcShaHash (String data, String key) {
    String HMAC_SHA1_ALGORITHM = "HmacSHA1";       
    String result = null;

    try {         
        Key signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
        mac.init(signingKey);
        byte[] rawHmac = mac.doFinal(data.getBytes());
        result = Base64.encodeBase64String(rawHmac);    
    }
    catch (Exception e) {
        e.printStackTrace(); 
    }       

    return result;
}

Here is my unit test code:

@Test
public void testCalcShaHash() {
    String data = "SampleIntegrationOwner2008-11-18T19:14:40.293Z";
    String key = "xBy/2CLudnBJOxOtDhDRnsDYq9HTuDVr2uCs3FMzoxXEA/Od9tOuwSC70+mIfpjeG68ZGm/PrxFf/s/CzwxF4Q==";
    String result = Utils.calcShaHash(data, key);
    assertEquals(result, "/UhwvT/kY9HxiXaOjpIc/BarBkc=");

}
like image 994
Shane Avatar asked Jun 02 '12 03:06

Shane


2 Answers

That looks like a Base64 encoded key. So I think you're going to need to do a base64 decode on it, then pass it to the HMAC. Something like this (just for illustration I haven't tested it, any errors are an exercise for the reader):

public String getHmacMD5(String privateKey, String input) throws Exception{
    String algorithm = "HmacSHA1";
    byte[] keyBytes = Base64.decode(privateKey);
    Key key = new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm); 
    Mac mac = Mac.getInstance(algorithm);
    mac.init(key); 
    return Base64.encode(mac.doFinal(input.getBytes()));
}
like image 126
chubbsondubs Avatar answered Oct 03 '22 19:10

chubbsondubs


One thing I noticed is that the hyphens are not normal hyphens. If you copy and paste them, they are not in the ASCII character set. All I can say for sure is that the hash length appears correct. The funny thing is, I couldn't get your code to produce the correct answer, even after putting the correct hyphens in. But no matter. It solved the problem. Huzzah!

like image 30
John Watts Avatar answered Oct 03 '22 18:10

John Watts