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'); }