Skip to content

Instantly share code, notes, and snippets.

@turret-io
Last active May 4, 2022 14:52
Show Gist options
  • Save turret-io/76946bf8475848710f7d to your computer and use it in GitHub Desktop.
Save turret-io/76946bf8475848710f7d to your computer and use it in GitHub Desktop.
Verify HMAC in NodeJS
var crypto = require('crypto');
// Added for safer string equality checking
var bufferEq = require('buffer-equal-constant-time');
var url = require('url');
var SHARED_SECRET = "sup3rs3cr3t!!";
function verifySignature(string_to_sign, signature, shared_secret) {
var hmac = crypto.createHmac('sha512', shared_secret);
hmac.write(string_to_sign);
hmac.end()
var sig = hmac.read();
// Compare buffers in constant time
return bufferEq(new Buffer(sig.toString('base64')), new Buffer(signature));
}
function verifyTime(decoded_json) {
obj = JSON.parse(decoded_json);
if(Math.round(new Date().getTime()/1000) - obj['timestamp'] > 30) {
throw new Error('Timestamp too far in the past');
}
return obj;
}
function parseQuery(query) {
var query_map = {};
query.split('&').map(function(el){
var split_at = el.indexOf('=')
query_map[el.slice(0, split_at)] = el.slice(split_at+1)
});
return query_map;
}
var url_string = '[QUERYSTRING]';
var parsed_url = url.parse(url_string);
var query_components = parseQuery(parsed_url.query);
var decoded_json = new Buffer(query_components.data, 'base64');
if(verifySignature(decoded_json, query_components.signature, SHARED_SECRET) === true) {
console.log('Valid signature');
// Verify timestamp
var payload = verifyTime(decoded_json);
console.log('Timestamp validated');
console.log(payload);
} else {
console.log('Invalid signature');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment