Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify HMAC fails #11

Open
Dawoodkhorsandi opened this issue Nov 18, 2021 · 3 comments
Open

Verify HMAC fails #11

Dawoodkhorsandi opened this issue Nov 18, 2021 · 3 comments

Comments

@Dawoodkhorsandi
Copy link

Dawoodkhorsandi commented Nov 18, 2021

Hi there,

I'm trying to verify the IPN using hmac, this is my sample code.

import express from "express";

import Coinpayments from 'coinpayments';
import { verify as verifyHMAC } from 'coinpayments-ipn';


app.use(express.json());
app.use(express.urlencoded({ extended: true,
                             verify: (req: express.Request, res, buf, encoding) => {
                                        req.rawBody = buf.toString();
                            }}
                          ));


app.post('/verify', async (req, res) => {
    const privateKey = process.env['PRIVATE_KEY'];
    const hmac = req.params['hmac'];

    console.log("First:  ", verifyHMAC(req.headers['hmac'], privateKey, req.body));
    console.log("Second:  ", verifyHMAC(req.headers['hmac'], privateKey, req.rawBody));
    res.send();
});


app.listen(3000, () => {
    logger.info(`Example app listening at http://localhost:3000`)
});
____________________________________________________
Output:

      First: false
      Second: false

Unfortunately verify always returns false.

@Dawoodkhorsandi
Copy link
Author

I was using the private key to validate the IPN, I switched to IPNSecret but now, bellow error is raised.

(node:84217) UnhandledPromiseRejectionWarning: CoinpaymentsIPNError: Payload is not an object
    at exports.verify (/home/dawood/repositories/abrnoc/billing/node_modules/coinpayments-ipn/lib/index.js:20:11)
    at CoinPaymentsGateway.<anonymous> (/home/dawood/repositories/abrnoc/billing/src/payment/gateways/coinPayments.gateway.ts:71:75)
    at Generator.next (<anonymous>)
    at /home/dawood/repositories/abrnoc/billing/src/payment/gateways/coinPayments.gateway.ts:8:71
    at new Promise (<anonymous>)
    at __awaiter (/home/dawood/repositories/abrnoc/billing/src/payment/gateways/coinPayments.gateway.ts:4:12)
    at CoinPaymentsGateway.verify (/home/dawood/repositories/abrnoc/billing/src/payment/gateways/coinPayments.gateway.ts:60:16)
    at PaymentService.<anonymous> (/home/dawood/repositories/abrnoc/billing/src/payment/payment.service.ts:75:38)
    at Generator.next (<anonymous>)
    at fulfilled (/home/dawood/repositories/abrnoc/billing/src/payment/payment.service.ts:5:58)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
(node:84217) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)

@Dawoodkhorsandi Dawoodkhorsandi changed the title Verify HMAC alway fails Verify HMAC fails Nov 18, 2021
@Dawoodkhorsandi
Copy link
Author

@OrahKokos
Thank you, I used this line of your code, And bellow example checks hmac correctly.

import express from "express";

import crypto from 'crypto';


app.use(express.json());
app.use(express.urlencoded({ extended: true,
                             verify: (req: express.Request, res, buf, encoding) => {
                                        req.rawBody = buf.toString();
                            }}
                          ));


const checkHmac = (theirHmac: string, IPNSecret: string, rawBody: string) => {
     const ourHmac = crypto.createHmac('sha512', IPNSecret).update(rawBody).digest('hex');
     return ourHmac == theirHmac;
}

app.post('/verify', async (req, res) => {
    const IPNSecret = process.env['IPNSecret'];
    const hmac = req.params['hmac'];
    console.log("is hmac valid: ",  checkHmac(hmac, IPNSecret, req.rawBody));
    res.send();
});

app.listen(3000, () => {
    logger.info(`Example app listening at http://localhost:3000`)
});


Output
_______________________________________
is hmac valid:  true

For future visitors: I didn't run the above code, Probably It will need some tweaks, they are simplified for demonstration, By the way, I'm new to typescript and the whole JS world.

@OrahKokos
Thanks again, I do not close the issue in case you have a comment for me. But feel free to close it.

@OrahKokos
Copy link
Owner

Greetings @Dawoodkhorsandi
Yeah, this lib is quite out of date and not a lot of testing has been done, so in time version 2.0.0 will change things, however I cannot specify when, since i'm quite busy.
If you are willing to experiment / contribute you can find the initial implementation here: https://github.com/OrahKokos/coinpayments-ipn/tree/version/2.0.0

Its at a point where it needs to be deployed to some env and tested.
When its properlly tested / bug fixed it will be fully released.
Other than that, feel free to close the ticket if you see no value for other users ( I don't mind it being open, since it does indicate that there are issues )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants