HMAC calculation

Using HMAC calculation secures the information sent between the shop and DIBS by applying the SHA-256 encryption algorithm on the information sent and one or two secure keys

Description

The MAC is designed to be used with the DIBS Payment Window and secures the key-value pairs which is considered part of the secured message. A key-value pair having a key which is either prefixed by "s_" or appears on the list of keys recognised by DIBS is considered a part of the secured message, and all other key-value pairs are ignored in the calculation. The key-value pairs in the secured message must be sorted by the key in ASCII-order with upper and lower case letters grouped seperately. The key and value must be separated by a "=", and each key-value pair should be separated by a "&".
The following example illustrates above rules:

If the following key-values are used in the call to DIBS:

Key Value
s_01 testValue
my_own_parameter value
language en_GB
Merchant 7dbe1a75-c5b5-e411-af22-005056890122
s_my_parameter 123456
amount 100

The message used for the calculation should be:

Merchant=7dbe1a75-c5b5-e411-af22-005056890122&amount=100&language=en_GB&s_01=testValue&s_my_parameter=123456

The MAC is calculated using the HMAC algorithm with SHA-256. The HMAC algorithm requires a message and one key. The message is the above message and the key is the merchant specific key found in the DIBS Administration:

DIBS Administration / Preferences / Integration

Calculation method

The HMAC calculation is done using the secret key found in the DIBS Admin. The calculation should be done as following:

MAC = HMAC-SHA256(hexDecode(K),M)

where K denotes the shop specific key found in the DIBS Administration and M is the previously mentioned message.

Example

M = "amount=100&currency=EUR"
K = "6926337856665a2b7931584a23346761247e396a714b3a644e797539362b3b5a572d3f24446a707d2d5164776e517543303925316433492352286f6b4e2a4368"
MAC = HMAC-SHA256(hexDecode(K), M) = a10df13e9702312e132d33063f186de4bfaedb6e9e19569de29e94c7e2043220

Calculation tool

You can use the tools on this page to verify if you are doing the HMAC calculations correctly. Note that you should not implement HMAC calculations via client-side scripting in your finished solution; these tools are only meant for testing.

MAC Key
MAC-String
Smart Form
URL encoder & decoder

HMAC calculation functions

/**
* calculateMac
* Calculates the MAC key from a set of parameters and a secret key
* @param array $msg Message array in key => value format
* @param string $K Secret HMAC key from DIBS Admin
* @return string
*/
function calculateMac($msg, $K) {
    //Decode the hex encoded key
    $K = pack('H*', $K);
    
    //Sort the key=>value array ASCII-betically according to the key
    ksort($msg, SORT_STRING);
    
    //Create message from sorted array.
    $msg = urldecode(http_build_query($msg));
    
    //Calculate and return the SHA-256 HMAC using algorithm for 1 key
    return hash_hmac("sha256", $msg, $K);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using System.Globalization;
using System.Security.Cryptography;
/**
* calculateMac
* Calculates the MAC key from a Dictionary<string, string> and a secret key
* @param params_dict The Dictionary<string, string> object containing all keys and their values for MAC calculation
* @param K_hexEnc String containing the hex encoded secret key from DIBS Admin
* @return String containig the hex encoded MAC key calculated
**/
static string calculateMac(Dictionary<string, string> params_dict, string K_hexEnc) {
  //Create the message for MAC calculation sorted by the key
  var keys = params_dict.Keys.ToList();
  keys.Sort(StringComparer.Ordinal);
  string msg = "";
  foreach (var key in keys) {
	if (key != keys[0]) msg += "&";
	msg += key + "=" + params_dict[key];
  }

  //Decoding the secret Hex encoded key and getting the bytes for MAC calculation
  var K_bytes = new byte[K_hexEnc.Length / 2];
  for (int i = 0; i < K_bytes.Length; i++) {
    K_bytes[i] = byte.Parse(K_hexEnc.Substring(i * 2, 2), NumberStyles.HexNumber);
  }

  //Getting bytes from message
  byte[] msg_bytes = Encoding.UTF8.GetBytes(msg);

  //Calculate MAC key
  var hash = new HMACSHA256(K_bytes);
  byte [] mac_bytes = hash.ComputeHash(msg_bytes);
  string mac = BitConverter.ToString(mac_bytes).Replace("-", "").ToLower();

  return mac;
}
/**
 * Dependencies:
 * Apache-Commons/Commons-Codec for Hex encoding/decoding
 * Codehaus/Jackson for JSON mapping
 */
/**
 * calculateMac Calculates the MAC from a given Map holding the post parameters and the secret key from DIBS Admin
 *
 * @param parameters Map<String, String> holding all post parameters
 * @param macKeyHex Hex encoded secret key from DIBS Admin
 * @return The MAC string calculated from the message and secret key using the hmac-sha256 algorithm
 */
public String calculateMac(Map<String, String> parameters, String macKeyHex) {
  try {
    // Sort the parameters ASCII-betically
    SortedMap<String, String> sortedParameters = new TreeMap<String, String>(parameters);

    // Build the string to calculate HMAC from
    StringBuilder macMsg = new StringBuilder();
    for (Map.Entry<String, String> param : sortedParameters.entrySet()) {
      if (macMsg.length() != 0) {
        macMsg.append('&');
      }
      macMsg.append(param.getKey()).append('=').append(param.getValue());
    }

    // Decode the hex-encoded secret key
    byte[] macKey = Hex.decodeHex(macKeyHex.toCharArray());

    // Calculate the hmac from message and secret key
    Mac hmacSha256 = Mac.getInstance("HmacSHA256");
    hmacSha256.init(new SecretKeySpec(macKey, "HmacSHA256"));
    byte[] mac = hmacSha256.doFinal(macMsg.toString().getBytes(Charset.forName("UTF-8")));

    // Return the hex-encoded hmac
    return Hex.encodeHexString(mac);
  } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
  } catch (InvalidKeyException e) {
    e.printStackTrace();
  } catch (DecoderException e) {
    e.printStackTrace();
  }
  return null;
}
Do you have question or need help?
Follow us
DIBS Payment Services
Stockholm +46 (0)8-527 525 00
Göteborg +46 031-600 800
København +45 7020 3077
Oslo +47 21 55 44 00