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:
http://i.imgur.com/hNkuRoq.png
EDIT2: They've sent me new(working) class, so maybe it will help someone :) http://pastebin.com/DKiXPMiE
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.