Search code examples
phpencryptioncryptography

Bókun signature generation; what am I missing?


I'm trying to connect to the Bókun Rest API. The documentation says:

Let's say our secret key is 23e2c7da7f7048e5b46f96bc91324800. Now, let's calculate the signature. First select values of the following fields:

Date = 2013-11-09 14:33:46 Access key = de235a6a15c340b6b1e1cb5f3687d04a HTTP method = POST Path = /activity.json/search?lang=EN&currency=ISK

So when concatenating the string (date+accesskey+httpmethod+path) becomes:

2013-11-09 14:33:46de235a6a15c340b6b1e1cb5f3687d04aPOST/activity.json/search?lang=EN&> currency=ISK

We then use this, along with the secret key to calculate the HmacSHA1 value for the signature, and Base64 encode it:

X-Bokun-Signature : XrOiTYa9Y34zscnLCsAEh8ieoyo=

So I'm trying to implement this with PHP but hit a rock wall, because the signature does not match the output of the test tool. This is my implementation:

$access_key = 'my_access_key';
$secret_key = 'my_secret_key';
$method = 'POST';
$path = '/activity.json/search?currency=EUR&lang=FI';
$date = '2022-08-31 12:00:00';

$signature_base = $date . $access_key . $method . $path;
$signature = hash_hmac('sha1', $signature_base, $secret_key, true);
$signature_sha1 = sha1($signature_base); // This is for test purposes
$signature_base64 = base64_encode($signature);

echo $signature_base; // 2022-08-31 12:00:00my_access_keyPOST/activity.json/search?currency=EUR&lang=FI
echo $signature_sha1; // 3e81b830958602b54419c61070582519460c36c6
echo $signature_base64; // 5q22t52R0qHk43ssRHs6kyLBSiw=

Then, these are the values I entered into the test tool: Test tool values

This is the test tool output:

hex: 3e81b830958602b54419c61070582519460c36c6

HEX: 3E81B830958602B54419C61070582519460C36C6

h:e:x: 3e:81:b8:30:95:86:02:b5:44:19:c6:10:70:58:25:19:46:0c:36:c6

base64: PoG4MJWGArVEGcYQcFglGUYMNsY=

What is interesting is that the hex output matches my test SHA1 hash but the base64 does not and I do not understand why. It leads me to suspect the output of hash_hmac but what am I doing wrong? I tried to use both false and true as the last (4th) argument. With false the base64 encoded output does not resemble the example in the documentation. It has too many characters in comparison. With true the resemblance is the same but the value is not.


Solution

  • Here's my own solution. It is in the context of Wordpress.

    function bokun_interface_get_results($page = 1, $page_size = 20, $lang = 'EN') {
        $options = get_option('bokun_options');
        $execution_time = isset($options['bokun_execution_time']) ? $options['bokun_execution_time'] : false;
    
        if ($execution_time) {
            ini_set('max_execution_time', $execution_time);
        }
    
        $access_key = $options['bokun_access_key'];
        $secret_key = $options['bokun_secret_key'];
    
        if (!$access_key || !$secret_key) {
            error_log("Bòkun REST API credentials not set. Can't continue with CRON job.");
            return;
        }
    
        $method = 'POST';
        $path = '/activity.json/search?currency=EUR&lang=' . $lang;
        $date = gmdate('Y-m-d H:i:s');
    
        $signature_base = $date . $access_key . $method . $path;
        $signature = hash_hmac('sha1', $signature_base, $secret_key, true);
        $signature_base64 = base64_encode($signature);
    
        $req = wp_remote_post('https://######.bokun.io' . $path, [
            'body' => '{"page": ' . $page . ', "pageSize": ' . $page_size . '}',
            'headers' => [
                'Content-Type' => 'application/json;charset=UTF-8',
                'X-Bokun-Date' => $date,
                'X-Bokun-AccessKey' => $access_key,
                'X-Bokun-Signature' => $signature_base64
            ]
        ]);
    
        $json_results = wp_remote_retrieve_body($req);
        $results = json_decode($json_results);
    
        return $results;
    }