Hash signature
Hash signature is generated and applied on both survey entry links and client redirect links. The hash signature on the link has the goal to prevent unauthorized communication and ensure the link has not been manipulated by third parties.
The party the link originates from is expected to apply a signature to the link, while the receiving party is expected to verify the hash signature received as a parameter on the link. Both link signing and hash verification processes require a shared Secret key between inBrain and the partner.
The steps needed to apply a hash signature to a link and verify hash signature are given below.
Link signing process
- Generate link by appending parameters to the base link
- Use generated link as a source
- Use shared Secret key as a key
- Calculate HMAC SHA256 hash using the source and the key
- Convert calculated hash to URL safe base64 string
- Append hash to the generated link (
&hash={hash}
)
hash
parameter must always be the last query parameter in the signed link
Hash verification process
- Normalize link by removing hash parameter including the preceding
&
(&hash={hash}
) - Use normalized link as a source
- Use shared Secret key as a key
- Calculate HMAC SHA256 hash using the source and the key
- Convert calculated hash to URL safe base64 string
- Compare calculated hash with the
hash
parameter value from the link - The request is accepted only when the hash values are equal, otherwise rejected
URL safe base64 string means the generated base64 string is modified to conform to url standards by replacing + (plus), / (slash) and = (equals) with - (dash), _ (underscore) and empty string respectively.
Hash calculation
The code snippets below implement the HMAC SHA256 hash calculation in different programming languages/technologies.
- C#
- Node.js
- PHP
using System;
using System.Security.Cryptography;
using System.Text;
var source = "SOURCE_LINK_HERE";
var key = "YOUR_SECRET_KEY_HERE";
var hash = default(string);
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
{
var contentBytes = Encoding.UTF8.GetBytes(source);
var hashBytes = hmac.ComputeHash(contentBytes);
hash = Convert.ToBase64String(hashBytes)
.Replace("+", "-")
.Replace("/", "_")
.Replace("=", string.Empty);
}
// proceed with link signing/hash verification
const crypto = require('crypto');
const source = "SOURCE_LINK_HERE";
const key = "YOUR_SECRET_KEY_HERE";
const hash = crypto
.createHmac('sha256', key)
.update(source, 'utf-8')
.digest('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/\=/g, '');
// proceed with link signing/hash verification
$source = "SOURCE_LINK_HERE";
$key = "YOUR_SECRET_KEY_HERE";
$hash = hash_hmac('sha256', $source, $key, true);
$hash = base64_encode($hash);
$hash = str_replace(['+', '/', '='], ['-', '_', ''], $hash);
// proceed with link signing/hash verification