PHP mcrypt问题

时间:2016-05-24 07:10:22

标签: php algorithm mcrypt

代码:

    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));
    }

问题是,如果我调用此函数,例如:

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

发生此错误:(函数中的第3个参数)

  

mcrypt_generic_init():密钥大小太大;提供长度:64,最大:32

第3个参数是静态键,它必须是64个字符长的字符串。它不能少。我尝试更改MCRYPT_RIJNDAEL_128 FOR MCRYPT_RIJNDAEL_256但发生此错误后(函数中的第二个参数)

  

mcrypt_generic_init():Iv大小不正确;供应长度:16,需要:32

我希望有人会帮助我:)。

编辑:

整个测试文件:

<?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">

根据这些数据,我得到了Sign功能的输出:6C4BBF9D2EC23D03E010AA94B5A7E174(INCORRECT)

门测试环境中的相同数据是标志:FCBA944122EF996CE6E50B6229753CA7(正确)

编辑:

作为图像的部分文档:

http://i.imgur.com/hNkuRoq.png

EDIT2:他们给我发了新的(工作)课程,所以也许会帮助别人:) http://pastebin.com/DKiXPMiE

1 个答案:

答案 0 :(得分:1)

您不应再使用MCrypt功能了。为什么?因为 MCrypt被视为放弃软件。该库不再被主动维护,并且a long list of known bugs很长时间没有修复。

我能给你的最好建议是:不要创建自己的加密内容。相反,请使用standard library instead


此外,在这种特定情况下,我已经发现您的签名功能存在问题。

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

换句话说,在使用DES密码(具有128位块大小的Rijndael)时,检查MCRYPT_RIJNDAEL_128算法的块大小。

另外:你的IV 必须是随机的 1 ,这就是IV的全部要点。


如果你真的想创建自己的加密库(你不应该),那么推荐的解决方案是使用PHP的OpenSSL扩展。但是:加密很难,非常难。一个好的加密包装器需要多个密码工作者和PHP专家一起工作,互相检查并仔细检查代码中的每个变化。仔细审查每一个决定。

1 :在这种情况下,随机意味着加密质量随机。对于php,这意味着您应该使用random_bytes()CSPRNG的一部分。