Answered HMAC and Marketplace Subscription Validation

  • Monday, August 20, 2012 3:09 PM
     
     

    I'm trying to replicate the HMAC256 signatures that the Marketplace is generating from the developer playground (https://datamarket.azure.com/developer/playground) to my app, but haven't been able to do so successfully.

    I've tried using the Shared Key Lite method for the Azure storage service (http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx), and played with a few minor variants in the hopes of hitting it lucky, but I haven't been able to replicate the signature.

    I'm deploying on a LAMP stack, so I'm really hoping that there's someone who can explain how to construct the signature from the headers and content the Marketplace sends out because a Windows-specific library will do me no good.

    Thanks for any help you can offer.

All Replies

  • Tuesday, August 21, 2012 8:21 PM
     
     Answered Has Code

    Turns out it is much easier than I thought it would be.  It didn't take any of the header manipulation or concatenation involved in oAuth.  Lesson for me is to always try the simplest stuff first.

    To save others time, it's just the x_marketplaceapptoken parameter stripped of the HMAC portion.  Then apply the hash to verify.

    In PHP:

    $_GET["x_marketplaceapptoken"] = "Audience=http%3a%2f%2fapi.marketplace.azure.com[...removed for brevity...]&HMACSHA256=ElvglvVOhSqxLWBK8VfbY815g%2fRA4jslXckF6DcQvGY%3d"; // from browser redirect on subscription or msg from Azure on Unsub
    
    define('AZURE_MYSECRET',"ABC...UVWX="); // from Azure account details
    define('REGEX_AZURE_SUBSCRIPTION_HMAC','/&HMACSHA256=[0-9A-Za-z%]+$/');
    
    if(preg_match(REGEX_AZURE_SUBSCRIPTION_HMAC,$_GET["x_marketplaceapptoken"],$sentHmac)) {
            $baseString = mb_substr($_GET["x_marketplaceapptoken"],0,(mb_strlen($_GET["x_marketplaceapptoken"])-mb_strlen($sentHmac[0])));
            $sentHmac = urldecode(mb_substr($sentHmac[0],mb_strlen('&HMACSHA256='))); // take first match, strip extraneous and decode
    
            $testHmac = base64_encode(hash_hmac('sha256',$baseString,base64_decode(AZURE_MYSECRET),true));
    
            if($testHmac === $sentHmac)
                    echo "is valid";
            else
                    echo "invalid";
    }


    • Marked As Answer by JT05 Tuesday, August 21, 2012 8:21 PM
    • Edited by JT05 Wednesday, August 22, 2012 3:10 AM shortened $_GET param to make more readable
    •