Search code examples
javaapihmacsha1

Problems with sigining a request using HMAC SHA-1 hashing for DigitEyes Api


I have been trying to sign a request to the DigitEyes Barcode api so that I may retrieve product information for a given barcode. However for requests, I must submit a signature which is generated using SHA-1 hashing of an authorization key and the UPC and base64 encrypting the result. T However no matter how much I try, I simply cannot get the signature which They have generated in an example.

The fields they used is: Authorization Key ("M" Code): Cf47U2b4d4Vt5Gz8

Sample UPC/EAN: 5201279013028

and they got: Sample Signature: Mb+LqZ7PM4bGxJDAWB/n7/LSj9A=

There are examples to do this as shown below however none of them are in JAVA, which is the language I am trying to do it in. The examples are shown below.

http://www.digit-eyes.com/specs/UPCAPIImplementation.pdf

The code that I am using is shown below and it works I believe but doesn't give me what they have.

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.Formatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

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

    private static String toHexString(byte[] bytes) {
        Formatter formatter = new Formatter();

        for (byte b : bytes) {
            formatter.format("%02x", b);
        }

        return formatter.toString();
    }

    public static String calculateRFC2104HMAC(String data, String key)
        throws SignatureException, NoSuchAlgorithmException, InvalidKeyException
{
    SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
    Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
    mac.init(signingKey);
    return toHexString(mac.doFinal(data.getBytes()));
}

public static void main(String[] args) throws Exception {
    String hmac = calculateRFC2104HMAC("5201279013028", "Cf47U2b4d4Vt5Gz8");

    System.out.println(hmac);
    byte[] encodedBytes = Base64.encodeBase64(hmac.getBytes());
    System.out.println("encodedBytes " + new String(encodedBytes));
    byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
    System.out.println("decodedBytes " + new String(decodedBytes));

    }
}

Solution

  • Looks like the issue is with toHexString()
    Don't convert mac.doFinal() output to hex
    Convert the output bytes directly to base64 to get the required result.