lexik / LexikPayboxBundle

LexikPayboxBundle eases the implementation of the Paybox payment system
MIT License
40 stars 47 forks source link

payment.ERROR: Signature is invalid. #7

Open soullivaneuh opened 11 years ago

soullivaneuh commented 11 years ago

I used fake paybox's card in dev env, and I have a invalid signature :

[2013-01-16 17:05:32] request.INFO: Matched route "lexik_paybox_ipn" (parameters: "_controller": "Lexik\Bundle\PayboxBundle\Controller\DefaultController::ipnAction", "time": "1358352320", "_route": "lexik_paybox_ipn") [] []
[2013-01-16 17:05:32] security.INFO: Populated SecurityContext with an anonymous Token [] []
[2013-01-16 17:05:32] payment.INFO: New IPN call. [] []
[2013-01-16 17:05:32] payment.INFO: amount=8252 [] []
[2013-01-16 17:05:32] payment.INFO: cmd=FR201301000001-1358352320 [] []
[2013-01-16 17:05:32] payment.INFO: auto=XXXXXX [] []
[2013-01-16 17:05:32] payment.INFO: trans=4353761 [] []
[2013-01-16 17:05:32] payment.INFO: type=CARTE [] []
[2013-01-16 17:05:32] payment.INFO: card=CB,VISA,EUROCARD_MASTERCARD [] []
[2013-01-16 17:05:32] payment.INFO: error=00000 [] []
[2013-01-16 17:05:32] payment.INFO: country=FRA [] []
[2013-01-16 17:05:32] payment.INFO: Sign=JDg9jvoFcM+i3JDOA6qy9Q6Gx6kFsyc+tymWVSTc7fYkNcwlKqF7SUdvBz6awxsD2tYuqkPtZjtdvTtYJm5mlnJdbrzPn3ixdjD7weTOxkJOcbUqqpmig3LDz2bpKajLFvE9Ut/+MRoemmSawpC3m2sQ2uFGkMtmFGCYfYQzzag= [] []
[2013-01-16 17:05:32] payment.INFO: amount=8252&cmd=FR201301000001-1358352320&auto=XXXXXX&trans=4353761&type=CARTE&card=CB%2CVISA%2CEUROCARD_MASTERCARD&error=00000&country=FRA [] []
[2013-01-16 17:05:32] payment.INFO: JDg9jvoFcM+i3JDOA6qy9Q6Gx6kFsyc+tymWVSTc7fYkNcwlKqF7SUdvBz6awxsD2tYuqkPtZjtdvTtYJm5mlnJdbrzPn3ixdjD7weTOxkJOcbUqqpmig3LDz2bpKajLFvE9Ut/+MRoemmSawpC3m2sQ2uFGkMtmFGCYfYQzzag= [] []
[2013-01-16 17:05:32] payment.ERROR: Signature is invalid. [] []

Here, my paybox form action :

    /**
     * @Route("/paybox")
     * @Template()
     */
    public function payboxAction()
    {
        $ref = $this->getRequest()->get('ref');
        /* @var $invoice Invoice */
        $invoice = $this->getDoctrine()->getRepository('SLLHMainBundle:Invoice')->findOneBy(array('ref' => $ref));

        /* @var $paybox PayboxRequest */
        $paybox = $this->get('lexik_paybox.request_handler');

        $paybox->setParameters(array(
            'PBX_CMD'           => $invoice->getRef().'-'.time(),
            'PBX_DEVISE'        => '978',
            'PBX_PORTEUR'       => 'test@test.net',
            'PBX_RETOUR'        => 'amount:M;cmd:R;auto:A;trans:T;type:P;card:C;countrycard:Y;error:E;country:I',
            'PBX_TOTAL'         => $invoice->getBalance() * 100,
            'PBX_TYPEPAIEMENT'  => 'CARTE',
            'PBX_TYPECARTE'     => 'CB,VISA,EUROCARD_MASTERCARD',
            'PBX_EFFECTUE'      => $this->generateUrl('sllh_front_payment_paybox_return', array('status' => 'success'), true),
            'PBX_REFUSE'        => $this->generateUrl('sllh_front_payment_paybox_return', array('status' => 'denied'), true),
            'PBX_ANNULE'        => $this->generateUrl('sllh_front_payment_paybox_return', array('status' => 'canceled'), true),
            'PBX_RUF1'          => 'POST',
            'PBX_REPONDRE_A'    => $this->generateUrl('lexik_paybox_ipn', array('time' => time()), true),
        ));

        $env = $this->container->getParameter('kernel.environment');

        return array(
            'invoice'   => $invoice,
            'url'       => $paybox->getUrl(),
            'form'      => $paybox->getForm()->createView(),
        );
    }

Did you already have thir error ? How did you fix it ?

Thanks for help.

soullivaneuh commented 11 years ago

I noticed one thing.

Here, the ipn routing:

lexik_paybox_ipn:
    pattern:  /payment-ipn/{time}
    defaults: { _controller: LexikPayboxBundle:Default:ipn }
    requirements:
        _method: GET|POST

And here, the ipnAction:

    public function ipnAction()
    {
        $payboxResponse = $this->container->get('lexik_paybox.response_handler');
        $result = $payboxResponse->verifySignature();

        return new Response($result ? 'OK' : 'KO');;
    }

The time parameter is not needed, so what is it ? It's maybe in relation with this issue...

Olineuve commented 11 years ago

The "time" parameter in the ipn route is actually not used, but it doesn't really matter. This was implemented in vue of a security feature. It is not causing bug since it's only a non used get parameter.

For the signature verification problem, the only thing i see that can cause trouble is the paybox public key changed, but the travis test still pass properly.

Do you tried remove the dash "-" on your "PBX_CMD" parameter. I don't remember exactly the format expected by Paybox but i'm wondering they wait for a string composed of alphanumerics characters.

soullivaneuh commented 11 years ago

I will test it.

In the stringified return data, I saw this : card=CB%2CVISA%2CEUROCARD_MASTERCARD

The , is url_encoded to %2, is it normal ?

Olineuve commented 11 years ago

Yes

soullivaneuh commented 11 years ago

I remove the - of PBX_CMD, nothing changed...

soullivaneuh commented 11 years ago

I changed a little bit your code in Response.php by following the example code given by Paybox and adding ssl error log.

And I found this error when I tried to get the public key:

[2013-01-17 14:23:04] payment.ERROR: Error while loading public key. error:0906D06C:PEM routines:PEM_read_bio:no start line [] []

This can help you a little more ?

Olineuve commented 11 years ago

I haven't been able to reproduce this error. It look like an environment issue.

Any news about it ? What is your operating system ? Your openssl version's ?

soullivaneuh commented 11 years ago

The error is not resolved yet, I ignore it for the moment...

OS: Linux 3.6.11-gentoo x86_64 OpenSSL: OpenSSL 1.0.0j 10 May 2012

fabienpomerol commented 11 years ago

One advice not really about your topic : be really carefull with "CB,VISA,EUROCARD_MASTERCARD", if you try real mastercard you'll see that it doesn't work !

You should use "CB" value which works with all kind of CARD

soullivaneuh commented 11 years ago

I think I already did using only "CB", will retry...

ibasaw commented 10 years ago

got same error

[2013-10-01 11:11:29] payment.INFO: New IPN call. [] []
[2013-10-01 11:11:29] payment.INFO: ref=7300|toto@titi.com|0|24cbfff0684e643b0cf68a4fb6c6f0bc|0 [] []
[2013-10-01 11:11:29] payment.INFO: autorisation=XXXXXX [] []
[2013-10-01 11:11:29] payment.INFO: trans=6191315 [] []
[2013-10-01 11:11:29] payment.INFO: abonnement=0 [] []
[2013-10-01 11:11:29] payment.INFO: paiement=CARTE [] []
[2013-10-01 11:11:29] payment.INFO: carte=CB [] []
[2013-10-01 11:11:29] payment.INFO: idtrans=3745027 [] []
[2013-10-01 11:11:29] payment.INFO: erreur=00000 [] []
[2013-10-01 11:11:29] payment.INFO: validite=1411 [] []
[2013-10-01 11:11:29] payment.INFO: IP=FRA [] []
[2013-10-01 11:11:29] payment.INFO: BIN6=111122 [] []
[2013-10-01 11:11:29] payment.INFO: digest=5B434C778490889697170E225029F56AFF19CA47 [] []
[2013-10-01 11:11:29] payment.INFO: Sign=H9e0LjyTU8h3vjaDXc2sKym7OnaPP5A5vh5kImbBFei6R58cEYwh3qLGffOF35zNK/CPlt7kfHblnZfgSXzbSyiU3ioe0rNHxGTjKRXWTkZOqDpG8Dr3ycWO247DkLthlY1vPPMWq9PfifQj2hi+C6h3x8nGHv7TvvfEPMq80Ag= [] []
[2013-10-01 11:11:29] payment.INFO: ref=7300%7Ctoto%40titi.com%7C0%7C24cbfff0684e643b0cf68a4fb6c6f0bc%7C0&autorisation=XXXXXX&trans=6191315&abonnement=0&paiement=CARTE&carte=CB&idtrans=3745027&erreur=00000&validite=1411&IP=FRA&BIN6=111122&digest=5B434C778490889697170E225029F56AFF19CA47 [] []
[2013-10-01 11:11:29] payment.INFO: H9e0LjyTU8h3vjaDXc2sKym7OnaPP5A5vh5kImbBFei6R58cEYwh3qLGffOF35zNK/CPlt7kfHblnZfgSXzbSyiU3ioe0rNHxGTjKRXWTkZOqDpG8Dr3ycWO247DkLthlY1vPPMWq9PfifQj2hi+C6h3x8nGHv7TvvfEPMq80Ag= [] []
[2013-10-01 11:11:29] payment.ERROR: Signature is invalid. [] []

the key is good, i check it with my PROD key on another project

ibasaw commented 10 years ago

i found it !

here how i solve this one in Response.php

    $publicKey = openssl_pkey_get_public($cert);

    $first = strpos ( $_SERVER ['REQUEST_URI'], '?' );
$qrystr = substr ( $_SERVER ['REQUEST_URI'], $first + 1 );
$pos = strrpos ( $qrystr, '&' );
$data = substr ( $qrystr, 0, $pos );
$pos = strpos ( $qrystr, '=', $pos ) + 1;
$this->signature = substr ( $qrystr, $pos );

    $this->signature = base64_decode ( urldecode ( $this->signature ) );

    $result = openssl_verify ( $data, $this->signature, $publicKey );
soullivaneuh commented 10 years ago

@ibasaw, can you send us a PR for exactly see the difference and merge the fix ?

Thanks ! :)

ibasaw commented 10 years ago

@Soullivaneuh , i will try, never do a PR before

fabienpomerol commented 10 years ago

The initSignature method normally do this job.

see https://github.com/lexik/LexikPayboxBundle/blob/master/Paybox/System/Base/Response.php#L80

what is the ouput of $this->signature without your fix ?

the request method is POST or GET ?

ibasaw commented 10 years ago

@fabienpomerol , without the fix, the ouput of the sign is broken chars with triangle, bad chars...

the request method is GET, param is in the url send by paybox ipn response

ibasaw commented 10 years ago

...

    $file = fopen(dirname(__FILE__) . '/../../../Resources/config/paybox_public_key.pem', 'r');
    $cert = fread($file, 8192);
    fclose($file);

    $publicKey = openssl_pkey_get_public($cert);

    $first = strpos ( $_SERVER ['REQUEST_URI'], '?' );
$qrystr = substr ( $_SERVER ['REQUEST_URI'], $first + 1 );
$pos = strrpos ( $qrystr, '&' );
$data = substr ( $qrystr, 0, $pos );
$pos = strpos ( $qrystr, '=', $pos ) + 1;
$this->signature = substr ( $qrystr, $pos );

    $this->signature = base64_decode ( urldecode ( $this->signature ) );

    $result = openssl_verify ( $data, $this->signature, $publicKey );

    $this->logger->info(Paybox::stringify($this->data));
    $this->logger->info(base64_encode($this->signature));

...

i had changed on this part of the file

soullivaneuh commented 10 years ago

All things has a beginning @ibasaw ! https://help.github.com/articles/fork-a-repo ;)

ibasaw commented 10 years ago

@Soullivaneuh , i had already read it, i just wondering where to clone the fork. generally, on SF2, when you fork a repo, where do you physically place the directory ? (not in the vendor)

soullivaneuh commented 10 years ago

You can use VCS repositories with composer: http://getcomposer.org/doc/05-repositories.md#vcs

After that, you can go to the vendor folder of the bundle, create a new branch and do your modification. ;)

ibasaw commented 10 years ago

no news ?

nykopol commented 10 years ago

I had the same issue. It's related to the ways paybox generate the signature.

If you use the PXB_REPONDRE_A option, the signature must be validated again the PBX_RETOUR option. If you configure the URL IPN by the admin of paybox, the signature must be validated again all the parameter of the IPN response except the Sign parameter.

I'm working on a fix.

nykopol commented 10 years ago

I finished the fix in PR #27 . Please tell me if it work for you.

ibasaw commented 10 years ago

@nykopol : don't work; got always signature is invalid

nykopol commented 10 years ago

@ibasaw Can you post again your action, log and config updated. Did you try with my PR #28 ? This fix is still waiting for merge and should fix your problem.

ibasaw commented 10 years ago

@nykopol i try with your pr #28 and always got an invalid signature check

(I had fixed a typo in your PR28, don't know if i dit it well by submitting a new PR)

for this error:

I do a payment, and on the response ipn url, i got an invalid signature check with KO

Signature verification : KO montant:3990 ref:1|xxx@xxx|89176843223ea7cf14bd1096be619b6b|0 autorisation:XXXXXX trans:8246233 abonnement:0 paiement:CARTE carte:CB idtrans:4344897 erreur:00000 validite:1412 IP:FRA BIN6:111122 digest:5B434C778490889697170E225029F56AFF19CA47

[2014-05-05 14:17:21] payment.INFO: New IPN call. [] [] [2014-05-05 14:17:21] payment.INFO: montant=3990 [] [] [2014-05-05 14:17:21] payment.INFO: ref=1|xxx@xxx|89176843223ea7cf14bd1096be619b6b|0 [] [] [2014-05-05 14:17:21] payment.INFO: autorisation=XXXXXX [] [] [2014-05-05 14:17:21] payment.INFO: trans=8246233 [] [] [2014-05-05 14:17:21] payment.INFO: abonnement=0 [] [] [2014-05-05 14:17:21] payment.INFO: paiement=CARTE [] [] [2014-05-05 14:17:21] payment.INFO: carte=CB [] [] [2014-05-05 14:17:21] payment.INFO: idtrans=4344897 [] [] [2014-05-05 14:17:21] payment.INFO: erreur=00000 [] [] [2014-05-05 14:17:21] payment.INFO: validite=1412 [] [] [2014-05-05 14:17:21] payment.INFO: IP=FRA [] [] [2014-05-05 14:17:21] payment.INFO: BIN6=111122 [] [] [2014-05-05 14:17:21] payment.INFO: digest=5B434C778490889697170E225029F56AFF19CA47 [] [] [2014-05-05 14:17:21] payment.INFO: Sign=V6ypoXPzQzw6MTYKmDPsYAKUxqrn5MOaJ/x7Q5PDyKn7cNLjofaR20wo+M6qdHuG9s8YLMiem0lW5cf1Vh8oTloIySsd7b187PbHpkjFCd9hhbxYod8DW8/kdnDYzd0XhOQoJYImu3Gv8UpVxhLpmVXC6CVFHtmz0J/YOk7BpPI= [] [] [2014-05-05 14:17:21] payment.INFO: montant=3990&ref=1%7Cxxx%40xxx%7C89176843223ea7cf14bd1096be619b6b%7C0&autorisation=XXXXXX&trans=8246233&abonnement=0&paiement=CARTE&carte=CB&idtrans=4344897&erreur=00000&validite=1412&IP=FRA&BIN6=111122&digest=5B434C778490889697170E225029F56AFF19CA47 [] [] [2014-05-05 14:17:21] payment.INFO: V6ypoXPzQzw6MTYKmDPsYAKUxqrn5MOaJ/x7Q5PDyKn7cNLjofaR20wo+M6qdHuG9s8YLMiem0lW5cf1Vh8oTloIySsd7b187PbHpkjFCd9hhbxYod8DW8/kdnDYzd0XhOQoJYImu3Gv8UpVxhLpmVXC6CVFHtmz0J/YOk7BpPI= [] [] [2014-05-05 14:17:21] payment.ERROR: Signature is invalid. [] []

ibasaw commented 10 years ago

it seems that paybox had changed their code, they encode the ref parameter...it wasn't before

ibasaw commented 10 years ago

now: is someone got a valid signature in DEV ?

Olineuve commented 10 years ago

I had the same error lately. I contacted the support but their answer whas not very usefull... In substance it was something like "I don't know. Do not verify the answer and just check if you have a payment reference or not."... So, I have no clue on how to fix this, for now...

ibasaw commented 10 years ago

lol...i am with support too and try to find why !

The problem is: the url call the ipn response with encoded characters for the ref parameter ans this is why the signature is invalid, if i modify the encoded characters to normal, and call it in my webbrowser: the signature is valid !

So i had encoded the PBX_CMD but it change nothing...always got an invalid signature.

@Olineuve : do you use this bundle in PROD ?

ibasaw commented 10 years ago

got news...

In fact, we must not to urlencode the ref PBX_CMD in the form.

In the response the ref PBX_CMD is urlencode, this is normal.

paybox send in the url response ipn the PBX_BIN6, but i demand only BIN6, so i got twice this parameter in the response, so the signature can't be right !

Waiting for an answer from the support...to remove the PBX_BIN6 in the response url

ghost commented 9 years ago

Hi,

I have a same problem, "Signature is invalid", in prod environment.

Have you solved the problem?

[2014-11-20 17:25:45] security.INFO: Populated SecurityContext with an anonymous Token [] [] [2014-11-20 17:25:45] payment.INFO: New IPN call. [] [] [2014-11-20 17:25:45] payment.INFO: Mt=31813 [] [] [2014-11-20 17:25:45] payment.INFO: Ref=CMD-1416500687 [] [] [2014-11-20 17:25:45] payment.INFO: Auto=XXXXXX [] [] [2014-11-20 17:25:45] payment.INFO: Erreur=00000 [] [] [2014-11-20 17:25:45] payment.INFO: Date=20112014 [] [] [2014-11-20 17:25:45] payment.INFO: Heure=17:26:17 [] [] [2014-11-20 17:25:45] payment.INFO: Sign=ktimFsnWNmFH4mr/2wl8umh3PVkdn4qyv+lQkJop0oGii6PU2kjbNNRrNF8sq6OVSDAWx+W+63Paf35H6isXW11o5JT3pXRsMGJV/nkBPB9uuO7p2RQg2chO9JuS9kN14oRpJE/15TkKNlzLkDvEanYG2bYPAmIsIkM4228LD1c= [] [] [2014-11-20 17:25:45] payment.INFO: Mt=31813&Ref=CMD-1416500687&Auto=XXXXXX&Erreur=00000&Date=20112014&Heure=17%3A26%3A17 [] [] [2014-11-20 17:25:45] payment.INFO: ktimFsnWNmFH4mr/2wl8umh3PVkdn4qyv+lQkJop0oGii6PU2kjbNNRrNF8sq6OVSDAWx+W+63Paf35H6isXW11o5JT3pXRsMGJV/nkBPB9uuO7p2RQg2chO9JuS9kN14oRpJE/15TkKNlzLkDvEanYG2bYPAmIsIkM4228LD1c= [] [] [2014-11-20 17:25:45] payment.ERROR: Signature is invalid. [] []

thnks

ibasaw commented 9 years ago

i will try again soon...

ghost commented 9 years ago

Ok, thnks.

ibasaw commented 9 years ago

@ahmed77 : did you tried my fork ?

ghost commented 9 years ago

@ibasaw : Yes, i tested with your fork and i still have the same problem.

ibasaw commented 9 years ago

ok, i will try again today

ghost commented 9 years ago

thnks.

ibasaw commented 9 years ago

@ahmed77 : Do you got an htacces with password on your website ? if, yes, it doesn't work

ghost commented 9 years ago

@ibasaw : No, i don't got an htacces with password on my website

ibasaw commented 9 years ago

got an invalid signature too again...again with support of paybox, wait for an answer...

ibasaw commented 9 years ago

got a valid sign today after a little commit on my fork, and i had modified the PBX_RETOUR value when you initialize the form

i got Pays in it and the url-ipn don't send back this variable in the url, so your verification is KO

today this is good:

Signature verification : OK montant:3990 ref:1|toto@toto.fr|6fa3ecaec29ad58f950809899e54abc9|0|4|ghv autorisation:XXXXXX trans:9513437 abonnement:0 paiement:CARTE carte:CB idtrans:5068347 erreur:00000 validite:1411 IP:FRA BIN6:111122 digest:5B434C778490889697170E225029F56AFF19CA47

ibasaw commented 9 years ago

@ahmed77 : did you tried again ?

ghost commented 9 years ago

@ibasaw : Thank you for your help. I tried again but the problem is still the same, i always "Signature is invalid"

ghost commented 9 years ago

I think the problem is a response from 'file_get_contents' who return FALSE, because when i replace '$this->parameters['public_key']' by the absolute file path, i don't have problem, the signature is ok.

ghost commented 9 years ago

In LexikPayboxExtension.php, $config['parameters']['public_key'] = DIR . '/../Resources/config/paybox_public_key.pem'; is not works but if i $config['parameters']['public_key'] = "/home/sites/project/vendor/lexik/paybox-bundle/Lexik/Bundle/PayboxBundle/Resources/config/paybox_public_key.pem", is ok.

Do you know why?

Edit: $this->parameters['public_key'] is always empty in Response.php file, if i want to signature is valid, i must to use $cert = file_get_contents("/home/sites/project/vendor/lexik/paybox-bundle/Lexik/Bundle/PayboxBundle/Resources/config/paybox_public_key.pem");

fjouatte commented 9 years ago

Hi guys,

I'm having the same kind of problem with my module. Sorry to write here it's not about the LexikPayboxBundle but it's the only one topic which seems nice to me.

The signature from the ipn is always incorrect. In the same time i'm able to validate the signature from the redirection (effectue, refuse and annule). I know that the ipn signature is only built with params from PBX_RETOUR. The only difference i noted is that the ref has been encoded.

Have you find a solution ? Does Paybox know what is the problem ?

ibasaw commented 9 years ago

@ahmed77 : i got this in my config.yml

public_key: "%kernel.root_dir%/config/paybox_public_key.pem"

i put the publick key in my app/config/ folder

i was aware about this problem with the key ;)

ibasaw commented 9 years ago

@fjouatte : check that your parameter went back form paybox as the same and in the same order as you pass in your PBX_RETOUR parameter: if not: signature is invalid !!!

fjouatte commented 9 years ago

Hi,

Sorry for answering so late. Thought my problem was solved but actually it wasn't. @ibasaw : I already checked that but thanks :)

The problem remains and I noticed something weird. The IPN requests sent from Paybox pre-production environment and prod environment are different. The 'Ref' param is encoded when using pre-production environment (&Ref=SAJ%2F2014%2F9446) and not when using production one (&Ref=SAJ/2014/9184).

Does someone notice that before ?

Regards