HMAC MD5 Validation with Node.js, Express and Trialpay
I'm trying to authenticate a message sent from TrialPay using Node.js and Express. TrialPay signs requests with an HMAC-MD5 hash, and provides these instructions on validating.
This is my code:
app.post('/trialpay', function(req, res) {
var key = "[MY MERCHANT KEY]";
var hash = req.header("TrialPay-HMAC-MD5");
var data = req.body.toString();
var crypted = require("crypto").createHmac("md5", key)
.update(data)
.digest("hex");
if (hash == crypted) {
res.writeHead(200, {"Content-Type": "plain/text"});
res.end("Success!");
} else {
throw new Error("Invalid TrialPay Hash");
}
});
This is, obviously, not working (hash doesn't match).
Disclaimer: I'm extremely new to Node.js, and have little Javascript experience, to begin with.
UPDATE
I did not realize that the link was protected.
TrialPay uses your Notification-Key (set in your account information) as the secret key to sign the HMAC. For GET requests the query string that follows the question mark (in the URL) is signed. For POST requests the entire POST body is signed.
Here is an example of how TrialPay instructs you to validate in Google App Engine (Python):
class MyHandler(webapp.RequestHandler):
def post(self):
key = '[YOUR MERCHANT KEY]'
tphash = self.request.headers['TrialPay-HMAC-MD5']
if hmacmd5(key,self.request.body) != tphash:
logging.info('invalid trialpay hash')
return
UPDATE 2
The req.body
prints out as:
{
oid: 'sample-order-id',
sid: 'customer-sid',
order_date: '04/24/2012',
timestamp: '04/24/2012 16:28:46',
first_name: 'customer-firstname',
last_name: 'customer-lastname',
email: 'customer@trialpay.com',
revenue: '10.00',
zip_code: '94041',
country: 'US'
}
这应该可以做到这一点:
var crypto = require('crypto');
function calculateSignature(key) {
return function(req, res, next) {
var hash = req.header("TrialPay-HMAC-MD5"),
hmac = crypto.createHmac("md5", key);
req.on("data", function(data) {
hmac.update(data);
});
req.on("end", function() {
var crypted = hmac.digest("hex");
if(crypted === hash) {
// Valid request
return res.send("Success!", { "Content-Type": "text/plain" });
} else {
// Invalid request
return res.send("Invalid TrialPay hash", { "Content-Type": "text/plain" }, 403);
}
});
req.on("error", function(err) {
return next(err);
});
}
}
app.post("/trialpay", calculateSignature("[MY MERCHANT KEY]"));
对于解析云码:(我测试过)关键是express.bodyParser将解析用于哈希的url编码字符串。
var parseExpressRawBody = require('parse-express-raw-body');
var queryString = require('querystring');
app.post('/trialpay',parseExpressRawBody(),function(req, res) {
var hmac, calculatedSignature,payloadStr=req.body.toString();
hmac = crypto.createHmac('md5', TrialPayMerchentKey);
hmac.update(payloadStr);
calculatedSignature = hmac.digest('hex');
if (req.headers['trialpay-hmac-md5'] === calculatedSignature) {
~~~~~~
链接地址: http://www.djcxy.com/p/10682.html