Image 01 Image 02

Secure Communication Over An API With Request Signatures

Posted on 13th February 2009 by Sameer
0

It’s a very common task for a web application to uniquely identify a visitor by a combination of username and password. However, not as trivial is identifying a third party attempting to use an API to access your web service on behalf of end users of their third party service. You often don’t want to force the end user to create a relationship with your service (such as would be required with OpenID) but instead allow the third party to use your API transparently (such as with Amazon). So, the task at hand is how to uniquely identify the third party making use of your API while preventing forgery and without requiring any sort of login system.

The solution starts with first providing each third party service with a unique public key. The public key is used to determine which third party service the request is claiming to be from. As expected, each public key has an associated private key. The private key is used to encrypt the message request into a signature. The API user will then send along that signature with the request. If the signature sent by the third party service matches the expected signature, then its safe to allow the request.

This method works because only you (the owner of the API) and the third party service have access to the private key. The third party encrypts its message using the private key and then sends along the encrypted version WITH the unencrypted version. The API owner then takes the unencrypted message and encrypts it with the private key (which it looked up based on the public key provided in the request). If the encrypted version generated by the API owner and the encrypted version sent in the request match, it can be trusted that the request came from the owner of the public key.

Here is some php code for the third party side of things. Basically the message is the url with an action of “friends.get”. The message is then encrypted and that encrypted signature is then appended to the url along with the public key. A request is then made to that url. The API owner will then process the request by verifying the identity of the requester (as mentioned above) and send back an appropriate response.

// your assigned public key which will be included in the api request
$public_key = "abcdefghijklmnopqrstuvxyz";
// your assigned private key which will always be hidden
$private key = "zyxvutsrqponmlkjihgfedcba";

// url of the api request which is essentially the message
$url = "http://www.apisite.com/api.php?action=friends.get";

// create a signature based on the api request using the private key
$signature = hash_hmac("sha512", $url, $private_key);

// the final api url with the public key and signature appended
$api_url = $url . "&public_key=" . $public_key . "&signature=" . $signature;

// fetch the url
$api_request_data = file_get_contents($api_url);


Leave a reply...