Skip to content

Instantly share code, notes, and snippets.

@josh-authy
Last active February 23, 2017 19:32

Revisions

  1. josh-authy revised this gist Feb 23, 2017. 1 changed file with 27 additions and 2 deletions.
    29 changes: 27 additions & 2 deletions verifyhmac.js
    Original file line number Diff line number Diff line change
    @@ -18,11 +18,36 @@ function verifyHMAC(proto, hostname, url, method, params, nonce, apikey, hmacsig
    var url = proto + "://" + hostname + url;

    // Sort the params.
    var sorted_params = qs.stringify(params).split("&").sort().join("&").replace(/%20/g, '+');
    var sorted_params = qs.stringify(params, { arrayFormat: 'brackets' }).split("&").sort(sortByPropertyOnly).join("&").replace(/%20/g, '+');

    var data = nonce + "|" + method + "|" + url + "|" + sorted_params;

    var computed_sig = crypto.createHmac('sha256', apikey).update(data).digest('base64');

    return hmacsig == computed_sig;
    }
    }

    /**
    * Sort by property only.
    * Normal JS sort parses the entire string so a stringified array value like 'events=zzzz'
    * would be moved after 'events=aaaa'.
    *
    * Instead we split tokenize the string around the '=' value and only sort alphabetically
    * by the property.
    *
    * @param {string} x
    * @param {string} y
    * @returns {number}
    */
    function sortByPropertyOnly(x, y){
    var xx = x.split("=");
    var yy = y.split("=");

    if (xx < yy) {
    return -1;
    }
    if (xx > yy) {
    return 1;
    }
    return 0;
    }
  2. josh-authy created this gist Sep 6, 2016.
    28 changes: 28 additions & 0 deletions verifyhmac.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    var qs = require('qs');
    var crypto = require('crypto');

    /**
    * Verify HMAC
    * @param proto
    * @param hostname
    * @param url
    * @param method
    * @param params
    * @param nonce
    * @param apikey
    * @param hmacsig
    * @returns {boolean}
    */
    function verifyHMAC(proto, hostname, url, method, params, nonce, apikey, hmacsig) {

    var url = proto + "://" + hostname + url;

    // Sort the params.
    var sorted_params = qs.stringify(params).split("&").sort().join("&").replace(/%20/g, '+');

    var data = nonce + "|" + method + "|" + url + "|" + sorted_params;

    var computed_sig = crypto.createHmac('sha256', apikey).update(data).digest('base64');

    return hmacsig == computed_sig;
    }