Webhook X-Shopify-Hmac-Sha256 calculation issue in Java

Babak_Morshediz
Shopify Partner
10 0 0

I've been trying to add verification to my webhooks to ensure no one abuses these endpoints. I have followed the instructions on https://help.shopify.com/api/reference/webhook step by step, and my code is (more or less) a mirror of the sample PHP code. Yet my Java code calculates the Hmac-Sha256 incorrectly. I need some help please.

Here is the sample:

final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
sha256_HMAC.init(new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"));
final String signature = Base64Other.encodeBytes(sha256_HMAC.doFinal(text.getBytes("UTF-8")));

"text" is the JSON payload (as a string, as I read it from the stream "as is") and "key" is the app's secret key (the one that is hidden and you need to click on it to show it).

Any help is greatly appreciated.

0 Likes
Jamie_D_
Shopify Staff (Retired)
Shopify Staff (Retired)
531 1 101

Hey Babak,

Here is some code I've used in the past to perform HMAC validation in Java.

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;

public class HmacWebhook
  public static void main (String[] args) throws java.lang.Exception
	{
		String secret = "hush";
		String message = "webhook_body";

		Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
		SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
		sha256_HMAC.init(secret_key);

		String encoded = Hex.encodeHexString(sha256_HMAC.doFinal(message.getBytes("UTF-8")));
		System.out.println(encoded);
	}
}

This relies on the Apache Commons library for Java.

Hope this helps. Perhaps some other Java developers can chip in with alternative solutions.

Babak_Morshediz
Shopify Partner
10 0 0

Thank you for your help. The value I receive from Shopify in the webhook header is like: 1N5wt62BwiSKLkTw/j1RuPM1tOWc7tAx53Fj+500Jpg= which is clearly not a hex value. Line by line, the rest of the sample you provided matches my sample. I will try it anyway.

0 Likes
Babak_Morshediz
Shopify Partner
10 0 0

So I used your method and the result looks like: "4f123e5468bf7aa2c4f32b535e666fe4ce9a15a65d5d97a587df9ae3a3afb51e" while I am looking for encoding that looks like "1N5wt62BwiSKLkTw/j1RuPM1tOWc7tAx53Fj+500Jpg= "

I am wondering if the input needs to be processed before I do the computation. If I am reading it the wrong way et cetera.

Do you have an actual working webhook in Java?

0 Likes
Babak_Morshediz
Shopify Partner
10 0 0

So, I have finally been able to get the correct response here. I actually hired someone on upwork.com to help, and he wrote the same code I had written. But then I noticed in his read function (of the POST payload), he didn't use UTF-8 charset. That is when I realized what was wrong. I assumed Shopify supports international characters as it is used worldwide. Clearly Shopify comes short in that arena, when it comes to its webhook events (I have to see other places if that is the case too).

So, the code I had origibally used works, but the way I read the payload was the issue.

0 Likes
icashout
New Member
2 0 0

Hello

 

I'm having the same issue, can let me know how you read the post request payload ? I tried reading the payload with or without UTF-* ecnoded but doesn't match the HMAC ? The strange thing test notification works but not the actual request

Here is my sample code:

Message is my payload.

Mac hmac = Mac.getInstance(HMAC_ALGORITHM);
SecretKeySpec key = new SecretKeySpec(secret.getBytes("UTF-8"), HMAC_ALGORITHM);
hmac.init(key);
String encoded = Hex.encodeHexString(hmac.doFinal(message.getBytes()));
return encoded;

 

Thank you

Venkat

0 Likes