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));
}
}
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.