1

I have a HMAC validation code in PHP which is like

$calculatedHmac = base64_encode(hash_hmac('sha256', json_encode($input), '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', true));
if($calculatedHmac === $this->app['request']->header('X-Shopify-Hmac-Sha256')) 
{
    echo "Correct HMAC";
}

Now, I am trying to do the same validation in GoLang. The corresponding code:

hash := hmac.New(sha256.New, []byte('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'))
inputData, _ := json.Marshal(input)
fmt.Println(string(inputData))
hash.Write(inputData)
base64EncodedStr := base64.StdEncoding.EncodeToString(hash.Sum(nil))
hexEncodedStr := hex.EncodeToString(hash.Sum(nil))
if requestHmac == base64EncodedStr {
    logger.GetEntryWithContext(ctx).Infow("JsonMarshal.Base64 worked", nil)
} else if hexEncodedStr == requestHmac {
    logger.GetEntryWithContext(ctx).Infow("JsonMarshal.Hex Encoding worked", nil)
}

Anything that I am doing wrong???

Input data: Actual HMAC: EUF2feuOuaQzh0bhSE8eCaI23BM0Qh+yBtmxNWyt8JQ=

JSON Input:

{"address1":"Ghar ka Address","address2":null,"auto_configure_tax_inclusivity":null,"checkout_api_supported":false,"city":"Bangalore ","cookie_consent_level":"implicit","country":"IN","country_code":"IN","country_name":"India","county_taxes":true,"created_at":"2021-03-06T11:54:22+05:30","currency":"INR","customer_email":"amit.vickey@razorpay.com","domain":"rzp-sample-store.myshopify.com","eligible_for_card_reader_giveaway":false,"eligible_for_payments":false,"email":"amit.vickey@razorpay.com","enabled_presentment_currencies":["INR"],"finances":true,"force_ssl":true,"google_apps_domain":null,"google_apps_login_enabled":null,"has_discounts":false,"has_gift_cards":false,"has_storefront":true,"iana_timezone":"Asia/Calcutta","id":55091921055,"latitude":12.9142148,"longitude":77.61210129999999,"money_format":"Rs. {{amount}}","money_in_emails_format":"Rs. {{amount}}","money_with_currency_format":"Rs. {{amount}}","money_with_currency_in_emails_format":"Rs. {{amount}}","multi_location_enabled":true,"myshopify_domain":"rzp-sample-store.myshopify.com","name":"RZP Sample Store","password_enabled":true,"phone":"","plan_display_name":"Developer Preview","plan_name":"partner_test","pre_launch_enabled":false,"primary_locale":"en","primary_location_id":61106618527,"province":"Karnataka","province_code":"KA","requires_extra_payments_agreement":false,"setup_required":false,"shop_owner":"Amit Vickey","source":null,"tax_shipping":null,"taxes_included":false,"timezone":"(GMT+05:30) Asia/Calcutta","updated_at":"2021-03-06T12:06:18+05:30","visitor_tracking_consent_preference":"allow_all","weight_unit":"kg","zip":"560076"}
Grokify
  • 11,326
  • 5
  • 39
  • 59
  • Are the JSON encodings in PHP and Go the same? – Cerise Limón May 11 '21 at 17:55
  • json_encode converts to JSON string, and json.Marshal converts into byte array which upon doing string(bytes) returns the same JSON. So yes the JSON encodings are same I guess. – user14041681 May 11 '21 at 17:58
  • 1
    Look at the actual strings to confirm that they are identical. The encoders might use different string encodings, whitespace between tokens and field orders. – Cerise Limón May 11 '21 at 18:02
  • order of the fields will also matter @CeriseLimón ? – user14041681 May 11 '21 at 18:26
  • 5
    If the two encoders write the fields in different orders, then the input to the HMAC is different. If the input to the HMAC is different, then the HMAC result will be different. – Cerise Limón May 11 '21 at 18:47
  • The code looks good. Use a simple one property JSON object like `{"foo":"bar"}` to confirm. The Base64 encoded value should match the PHP output. The issue as others have mentioned is JSON key order in JSON encoding. See this issue for more: https://github.com/golang/go/issues/27179 and https://stackoverflow.com/questions/20912492/json-encode-not-preserving-order – Grokify May 12 '21 at 00:04
  • sure will try this. another doubt, just relevant this this only. In GoLang I have to write utility that if a map have index as keys like `{"0":"abc","1":"bcd","2":"def"}`, I need to an array of values out of it i.e. `["abc", "bcd", "def"]` – user14041681 May 12 '21 at 08:19

0 Answers0