Wednesday, September 22, 2010

10:23 PM
Many times a requirement arises where we are supposed to expose an API for intended users, who can use these API endpoints to GET/POST data on our servers. But how do we verify that only the intended users are using these API’s and not any hacker or attacker. 

In this blog post, I will show you the most elegant way of adding content verification using hash_hmac (Hash-based Message Authentication Code) in PHP. This will allow us to restrict possible misuse of our API by simply issuing an API key for intended users.
Here are the steps for adding content verification using hmac in PHP:
  • Issue $private_key and $public_key for users allowed to post data using our API. 
  • Users having these keys can now use following sample script (hmac-sender.php) to submit data:

        // User Public/Private Keys
        $private_key = 'private_key_user_id_9999';
        $public_key = 'public_key_user_id_9999';

        // Data to be submitted
        $data = 'This is a HMAC verification demonstration';

        // Generate content verification signature
        $sig = base64_encode(hash_hmac('sha1', $data, $private_key, TRUE));

        // Prepare json data to be submitted
        $json_data = json_encode(array('data'=>$data, 'sig'=>$sig, 'pubKey'=>$public_key));

        // Finally submit to api end point
        submit_to_api_end_point("http://yoursite.com/hmac-receiver.php?data=".urlencode($json_data));

At hmac-receiver.php, we validate the incoming data in following fashion:

        function get_private_key_for_public_key($public_key) {
                // extract private key from database or cache store
                return 'private_key_user_id_9999';
        }

        // Data submitted
        $data = $_GET['data'];
        $data = json_decode(stripslashes($data), TRUE);

        // User hit the end point API with $data, $signature and $public_key
        $message = $data['data'];
        $received_signature = $data['sig'];
        $private_key = get_private_key_for_public_key($data['pubKey']);
        $computed_signature = base64_encode(hash_hmac('sha1', $message, $private_key, TRUE));

        if($computed_signature == $received_signature) {
                echo "Content Signature Verified";
        }
        else {
                echo "Invalid Content Verification Signature";
        }

Where to use such verification?

This is an age old method for content verification which is used widely in a variety of applications. Below are a few places where hmac verification finds a place:

  • If you have exposed an API for your vendors to submit requested data
  • If you are looking to enable third party applications in your website. Similar to developer application model of facebook.

Hope you liked the post. Do leave your comments.
Enjoy!

0 comments: