1

Code:

    function sign($data,$iv,$hexKey){
        $_cipher    =   mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC,    '');
        $binKey32 = hex2bin($hexKey);
        $block  =   mcrypt_get_block_size('des',    MCRYPT_MODE_CBC);
        $pad    =   $block  - (strlen($data)    %   $block);
        $data   .=  str_repeat(chr($pad),   $pad);
        mcrypt_generic_init($_cipher,   $hexKey,    $iv);
        $result =   mcrypt_generic($_cipher,    $data);
        mcrypt_generic_deinit($_cipher);
        return  strtoupper(substr(bin2hex($result),0,32));
    }

Problem is that if I call this function, for example:

$sign = sign("string", "strinGGnirts", "1234567812345678123456781234567812345678123456781234567812345678");

this error occurrs: (3rd parameter in function)

mcrypt_generic_init(): Key size too large; supplied length: 64, max: 32

That 3rd parameter is static key, it must be 64 char long string. It can't be less. I've tried to change MCRYPT_RIJNDAEL_128 FOR MCRYPT_RIJNDAEL_256 but after this error occurrs (2nd parameter in function)

mcrypt_generic_init(): Iv size incorrect; supplied length: 16, needed: 32

I hope that there is someone who will help me :)

EDIT:

Whole testing file:

<?php
function sign($data,$iv,$hexKey){
    $_cipher    =   mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC,    '');
    $binKey32 = hex2bin($hexKey);
    $block  =   mcrypt_get_block_size('des',    MCRYPT_MODE_CBC);
    $pad    =   $block  - (strlen($data)    %   $block);
    $data   .=  str_repeat(chr($pad),   $pad);
    mcrypt_generic_init($_cipher,   $binKey32,  $iv);
    $result =   mcrypt_generic($_cipher,    $data);
    mcrypt_generic_deinit($_cipher);
    return  strtoupper(substr(bin2hex($result),0,32));
}

$sign = sign("demoOMED"."10.50"."EUR"."10000"."Michal"."Test"."2015-05-05 14:57:13", "demoOMEDDEMOomed", "1234567812345678123456781234567812345678123456781234567812345678");
print_r($sign);?>
<form method="post" action="https://doxxsl-staging.24-pay.eu/pay_gate/paygt" >
<input type="hidden" name="Mid" value="demoOMED">
<input type="hidden" name="EshopId" value="11111111">
<input type="hidden" name="PreAuthProvided" value="false">
<input type="hidden" name="MsTxnId" value="10000">
<input type="hidden" name="Amount" value="10.50">
<input type="hidden" name="CurrAlphaCode" value="EUR">
<input type="hidden" name="ClientId" value="170">
<input type="hidden" name="FirstName" value="Michal">
<input type="hidden" name="FamilyName" value="Test">
<input type="hidden" name="Email" value="test@tes.sk">
<input type="hidden" name="Street" value="Kalov">
<input type="hidden" name="Zip" value="01001">
<input type="hidden" name="City" value="Žilina">
<input type="hidden" name="Country" value="SVK">
<input type="hidden" name="Timestamp" value="2015-05-05 14:57:13">
<input type="hidden" name="Sign" value="<?php echo $sign;?>">
<!-- PARAMETER DEBUG USE ONLY WHILE TESTING -->
<input type="hidden" name="Debug" value="true">
<input type="submit" value="Test">

With these data I got output in Sign function: 6C4BBF9D2EC23D03E010AA94B5A7E174 (INCORRECT)

With same data in Gate Testing Enviroment is Sign: FCBA944122EF996CE6E50B6229753CA7 (CORRECT)

Edit:

Part of the documentation as an image:

https://i.stack.imgur.com/tzuJC.png

EDIT2: They've sent me new(working) class, so maybe it will help someone :) http://pastebin.com/DKiXPMiE

UareBugged
  • 178
  • 1
  • 11
  • It's function from developers of one payment gate that I need to use. Practically I need same output but I need function that will work. Because without correct output I can't access to gate. So I can't make function with better crypting or something like that. – UareBugged May 24 '16 at 09:05
  • There is part of documentation where they are talking about it. How should that Sign look like etc. http://i.imgur.com/hNkuRoq.png. Key is that 64 char long 3rd parameter. IV is 2nd parameter. It's just string + reversed string. First parameter is just that combination of few strings – UareBugged May 24 '16 at 09:22
  • http://stackoverflow.com/a/1628177/5006740 – strangeqargo May 24 '16 at 09:30
  • Yea @strangeqargo , I've already tried this but output is still different from output that I need. – UareBugged May 24 '16 at 09:33
  • I'm posting to highlight that your IV should be randomly generated for every new signature. You should never use the same IV when you encrypt / sign. The IV should be distributed publicly along with encrypted ciphertext. – Mjh May 24 '16 at 09:59
  • I've edited post description(Added code as you wrote). But output is still different. Current output: 6C4BBF9D2EC23D03E010AA94B5A7E174 , Correct Output: FCBA944122EF996CE6E50B6229753CA7 – UareBugged May 24 '16 at 10:02
  • As i said @Mjh , It's not my choice. These things are static and I can't do nothing with it. I just need to make it work – UareBugged May 24 '16 at 10:03
  • Mid is static string from administration. I have now access to sandbox gate and they have static Mid for sandbox: "demoOMED" . So practically IV should be: "demoOMEDDEMOomed". Key is static key for every user in their system. And sandbox has static key: "8x12345678" -> "1234567812345678123456781234567812345678123456781234567812345678" – UareBugged May 24 '16 at 10:27
  • Output is again: 6C4BBF9D2EC23D03E010AA94B5A7E174 which is same as last time. – UareBugged May 24 '16 at 11:10
  • Thanks for link :) Problem is that I can't choose what to use and what not. I have instructions and available libraries that can I use for that page. If it would be my choice, I would find other solution but I'm not in that situation – UareBugged May 25 '16 at 15:16
  • 1
    Well, I've contacted their support and they've sent me working function (finally) . Thanks for your time :) – UareBugged May 26 '16 at 18:54
  • Alright :) I've edited post, I've added link to code (It's little bit long so I uploaded it to pastebin) :) – UareBugged May 28 '16 at 07:29
  • 1
    Thanks for the update to the code. The mistake I made was to use a $mid of 'demoOMEDDEMOomed' instead of 'demoOMED'. I am glad that you got it sorted out. phew :) – Ryan Vincent May 28 '16 at 12:16

1 Answers1

1

You should not use the MCrypt functions anymore. Why? because MCrypt is considered abandonware. The library is no longer actively maintained and a long list of known bugs are not fixed since a long time.

The best advice I can give you is: do not create your own crypto stuff. Instead, use a standard library instead.


Also, in this specific case, I can already spot issues with your signing function.

<?php
...
$_cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', CRYPT_MODE_CBC, '');
...
$block = mcrypt_get_block_size('des', MCRYPT_MODE_CBC);

In other words, you check for the block size of the DES algorithm while using the MCRYPT_RIJNDAEL_128 cipher (Rijndael with 128 bits block size).

Also: your IV must be random1, that is the whole point of the IV.


If you reaally want to create your own crypto library (you shouldn't) then the recommended solution is to use PHP's OpenSSL extension. But: crypto is hard, exceptionally hard. A good crypto wrapper requires multiple cryptographers and PHP specialists working together, checking each other and double checking each change in the code. Scrutinizing every decision.

1: random in this case means crypto quality random. For php this means you should use random_bytes(), part of CSPRNG.

Jacco
  • 23,534
  • 17
  • 88
  • 105
  • It's function from developers of one payment gate that I need to use. Practically I need same output but I need function that will work. Because without correct output I can't access to gate. So I can't make function with better crypting or something like that – UareBugged May 24 '16 at 10:10
  • If this is meant to be used with a payment gateway, you should file a bug report and, depending on your country, may be required to report them to the relevant authorities for using unsafe crypto in relation to payment data. – Jacco May 24 '16 at 10:13
  • I had no clue that `libsodium` was exposed to PHP and I agree with everything you wrote, +1 from me and thanks for the `libsodium` tip. For the OP: you can recreate everything you need using `openssl` library instead of `mcrypt`. However, the "security" they implemented contains a huge hole and you should file a bug report like Jacco wrote. – Mjh May 24 '16 at 10:27