Emulating Shopify's webhook validation in liquid

As part of shopify’s web hook, they pass a validation key.

Basically, it’s this:

  1. convert the API key to to UTF8 bytes (keyBytes = UTF8Bytes(apiKey))
  2. create an HMACSHA256 hash of the body of the request and the converted api key (hmacBytes=HashHmacSha256(“some string”, keyBytes))
  3. convert the above result to base64 (validationKey=BytesToBase64(hmacBytes))

I’m trying to emulate this in liquid using :
“some string”| hmac_sha256:“my api key”| base64_encode

but “my api key” needs to get converted to UTF8Bytes

Is this possible? Of course, it’s doable in javascript but that exposes the API key.

The whole issue boils down to the liquid hmac256 implementation. It returns nothing like what javascript returns which is what every site I’ve tested returns – a 44-byte string. I don’t know what shopify has done, but this is not hmac sha256.

Thank you

You can use the
to_json
filter to convert your string into a JSON object, which will be UTF-8 encoded.

Ok. Well, this was sort of working all along and had nothing to do with UTF8 encoding. Hmac_sha256 does that in the background.

The issue was with the Base64_encoding. This encodes a character string, not a hex value, which hmac_sha256 returns. Since there is no Hex conversion in liquid, I simply did that part in javascript:

liquid:
assign gcHash2=customer.email | hmac_sha256: "my secret key"

javascript:
gcHash2=btoa(String.fromCharCode.apply(null, '{{ gcHash2 }}'.match(/\w{2}/g).map(function(a) { return parseInt(a, 16) })));

Thanks…it’s all fixed.