In addition to the method call, format and variables sent on the URL line (discussed in yesterday’s article), you are required to send some extra information in the headers of the outgoing HTTP request.
From the API Documentation:
- X-Searunner-apikey Your public API key you were given when signing
up for a developer account.
- X-Searunner-time A float representation of “now” including
milliseconds (like that produced by the php function microtime(true))
- X-Searunner-hmac-algo The algorithm used for generating the HMAC,
like sha1, sha256, MD5 etc.
- X-Searunner-hmac The HEX representation of the HMAC signing the
The following headers are only required when sending POST data:
- X-Searunner-posthash A hash of the POST data packet.
- X-Searunner-posthash-algo The algorithm used to create the POST
hash, eg md5, sha1 etc.
- Content-type The content type of the data (default:
- Content-Length The length of the POST data in bytes.
Initially, this may look like rather a lot to take in, but it is actually quite simple.
The two algorithm selection fields
X-Searunner-posthash-algo give the name of the algorithm used –
sha256 etc. Letting the client specify the algorithm used lets us get around issues with buggy/missing algorithm implementations. For example, we use MD5 for the Java library as this removes the need to install a third party JCE.
Where possible you should probably try and use “
sha256” for HMAC and “
sha1” for hashing your post data, since over time we will likely “retire” the weaker algorithms.
X-Searunner-time timestamps the request, while
Content-Length (for POST requests) are pretty much self explanatory.
X-Searunner-posthash ensures that the POST body can not be modified, and it is a lower case hexadecimal representation of the desired HASH algorithm, taken over all the data in the POST body, take a look at this pseudo code:
hash = algorithmFactory( //X-Searunner-posthash-algo// );
hash.update( //POST DATA// );
Finally, the field
X-Searunner-hmac contains a signature which lets the elggVoices server guarantee that it was you that sent the request (rather than someone pretending to be you) and that the contents of the request have not been modified. This is where your secret key comes in, and is the reason why it is important that you keep it safe!
From the manual:
A HMAC is a simple cryptographic signature, in this case is formed over the
- The time header eg,
- Your API key
- The GET query string, eg “
format=xml&method.example&variable=foo“. It is
important to note two things, firstly that the preceding “?” character has
been dropped, and second that the order is identical to the order they
appear on the URL line.
- If this is a POST request, the hash of the POST data.
Take a look at this pseudo code:
hmac_cipher = algorithmFactory( //X-Searunner-hmac-algo// );
hmac_cipher.update( //X-Searunner-time// );
hmac_cipher.update( //X-Searunner-apikey// );
hmac_cipher.update( //GET VARIABLES IN CALL ORDER// );
if (POST CALL) hmac_cipher.update( //X-Searunner-posthash// );
To form the HMAC, each variable’s string representation is turned into a string of bytes. This byte string is fed in turn into the HMAC algorithm which spits out a HMAC signature which is then converted into a lower case hexadecimal string. These are Octet strings, ensure that when adding the strings to the cipher that your language doesn’t convert it into unicode!
Note that the order in which you add each field is VERY IMPORTANT.
Next comes the server response…