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="[email protected]">
<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.sstatic.net/tzuJC.png

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

13
  • 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. Commented May 24, 2016 at 9:05
  • There is part of documentation where they are talking about it. How should that Sign look like etc. 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 Commented May 24, 2016 at 9:22
  • stackoverflow.com/a/1628177/5006740 Commented May 24, 2016 at 9:30
  • 1
    Well, I've contacted their support and they've sent me working function (finally) . Thanks for your time :) Commented May 26, 2016 at 18:54
  • 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 :) Commented May 28, 2016 at 12:16

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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
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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.