admin管理员组文章数量:1355658
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: '[email protected]',
revenue: '10.00',
zip_code: '94041',
country: 'US'
}
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: '[email protected]',
revenue: '10.00',
zip_code: '94041',
country: 'US'
}
Share
Improve this question
edited Apr 25, 2012 at 15:19
Paul Burke
asked Apr 24, 2012 at 19:52
Paul BurkePaul Burke
25.6k9 gold badges67 silver badges62 bronze badges
10
-
1
Your link doesn't work -- it won't let me log in. That said, you should stay clear of
throw
ing inside your request handlers (basically, anywhere in node). Accept the third parameter (the callback,next
in express lingo) and pass the error tonext
instead. Or even better, handle the error here, where you can, andres.send(403, 'Invalid TrialPay Hash')
. Also, you don't mention what kind of data you are posting -- it would be interesting to see whatreq.body
and especiallyreq.body.toString()
contains, if you couldconsole.log
that. – Linus Thiel Commented Apr 24, 2012 at 20:03 -
Thanks for the ment and advice @LinusGThiel. When I tried
console.log(req.body.toString());
it only prints out "[object Object]". Please excuse my ignorance, here. – Paul Burke Commented Apr 24, 2012 at 20:13 -
That's what I suspected! What does
console.log(req.body)
give you? – Linus Thiel Commented Apr 24, 2012 at 20:21 - You are filling in [MY MERCHANT KEY] with the correct data, right? – ControlAltDel Commented Apr 24, 2012 at 20:31
-
Okay,
console.log(req.body)
gives me back the list of JSON parameters. So, how do I pass this tocrypto.update()
? It needs a String or Buffer. I tried both (perhaps incorrectly) and neither worked. – Paul Burke Commented Apr 24, 2012 at 20:32
2 Answers
Reset to default 6This should do the trick:
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(crypto.timingSafeEqual(
Buffer.from(crypted),
Buffer.from(hash.padEnd(crypted.length))
)) {
// 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]"));
For Parse Cloud Code:(I have tested) The point is express.bodyParser will parse the url encoded string which is used to hash.
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) {
~~~~~~
本文标签:
版权声明:本文标题:javascript - HMAC MD5 Validation with Node.js, Express and Trialpay - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743960865a2569000.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论