HMAC SHA1 Signature in Java

18,558

Solution 1

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!

Solution 2

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()));
}
Share:
18,558

Related videos on Youtube

Shane
Author by

Shane

Updated on June 04, 2022

Comments

  • Shane
    Shane about 2 years

    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=");
    
    }
    
    • John Watts
      John Watts about 12 years
      A larger excerpt from the documentation might help. 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.
    • Shane
      Shane about 12 years
      @John Watts - your comment about the dashes was correct. I copied and pasted the text from a Word document. The dashes were not standard ASCII characters. By putting normal dashes in, the result was correct without needing to decode the key. Please add your comment as an answer.
  • Shane
    Shane about 12 years
    I tried that, but still didn't get the correct answer. See code sample above.
  • John Watts
    John Watts about 12 years
    @Shane Can you copy your updated SSCE from the original question here? I copied your original code, updated it with proper hyphens and it still fails for me. I think there is another difference we still haven't identified that I would like to preserve for posterity.
  • Santhosh
    Santhosh almost 10 years
    @chubb Is is possible to decrypt the value using the key that is used up for encryption ?
  • chubbsondubs
    chubbsondubs over 9 years
    No HMAC is a one way hash that uses a public/private key pair to validate that the hash was generated using that specific key. In normal one way hash functions (SHA1, MD5, SHA256, etc) there are no secret keys involved so anyone who knows the algorithm can create a hash. HMAC allows you to ensure only the person/system holding a specific key generated this hash and no one else.