Security



The Payment Link product requires a SHA-1 hash signature on redirects into the Magnatefy. This greatly reduces fraudulent clients and link manipulation. Redirects taking clients from the Magnatefy back to you will be hashed as well. You are responsible for ensuring client quality prior to sending them into the Magnatefy. In addition to URL hashing, we recommend implementing other security measures, such as Invisible ReCaptcha.

Hash Signature

A hash signature is required on all entry links to prevent unauthorized use. Your client success manager will provide you with a secret key to generate hash signatures. The hash signature should be created using HMAC SHA1 with your private key, then base64 URL encoded. Your base string should include the entire URL, up to and including the & preceding the hash variable. Code snippets are available on the How does this work?. The hash signature that is generated must be appended to the end of the URL string.

Please note that if any of the following characters are included in the hash, they should be replaced, so they conform to web standards.

Original Substitute
+ - (dash)
/ _ (underscore)
= (empty string)

How does this work?

Python
import hmac
import hashlib
import base64

encoded_key = key.encode('utf-8')
encoded_URL = URL.encode('utf-8')
hashed = hmac.new(encoded_key, msg=encoded_URL, digestmod=hashlib.sha1)
digested_hash = hashed.digest()
base64_encoded_result = base64.b64encode(digested_hash)
final_result = base64_encoded_result.decode('utf-8').replace('+', '-').replace('/', '_').replace('=', '')

PHP
$encodedKey = utf8_encode($key);
$encodedURL = utf8_encode($url);
$hashed = hash_hmac('sha1', $encodedURL, $encodedKey);
$digestedHash = pack('H*',$hashed);
$base64EncodedResult = base64_encode($digestedHash);
$finalResult = str_replace(["+","/","="],["-","_",""],utf8_decode($base64EncodedResult));

Node.js
const Crypto = require('crypto');

const hash = Crypto.createHmac('sha1', key).update(url, 'utf-8').digest('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
const final_result = encodeURIComponent(hash);

Java
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

private static String hashMe(String url, String keyString) throws
    UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
    SecretKeySpec key = new SecretKeySpec((keyString).getBytes("UTF-8"), "HmacSHA1");
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(key);
    byte[] bytes = mac.doFinal(url.getBytes("UTF-8"));
    byte[] encodedBytes = Base64.getEncoder().encode(bytes);
    String finalResult = new String(encodedBytes);
    return finalResult.replace("+", "-").replace("/", "_").replace("=", "");
}

Ruby
require 'openssl'
require 'base64'

encoded_key = key.encode('utf-8')
encoded_URL = url.encode('utf-8')
digested_hash = OpenSSL::HMAC.digest("sha1", encoded_key, encoded_URL)
base64_encoded_result = Base64.encode64(digested_hash)
final result = base64_encoded_result.force_encoding('utf-8').gsub('+', '-').gsub('/', '_').gsub('=', '').strip