代码之家  ›  专栏  ›  技术社区  ›  Adam Hopkinson

使用mcrypt跨web服务传递数据失败

  •  2
  • Adam Hopkinson  · 技术社区  · 16 年前

    我正在编写一个错误处理程序脚本,它对错误数据(文件、行、错误、消息等)进行加密,并将序列化数组作为POST变量(使用curl)传递给一个脚本,然后将错误记录在中央数据库中。

    我在一个文件中测试了加密/解密功能,数据加密和解密都很好:

    define('KEY', 'abc');
    define('CYPHER', 'blowfish');
    define('MODE', 'cfb');
    
    
    function encrypt($data) {
        $td = mcrypt_module_open(CYPHER, '', MODE, '');
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        mcrypt_generic_init($td, KEY, $iv);
        $crypttext = mcrypt_generic($td, $data);
        mcrypt_generic_deinit($td);
        return $iv.$crypttext;
    }
    
    function decrypt($data) {
        $td = mcrypt_module_open(CYPHER, '', MODE, '');
        $ivsize = mcrypt_enc_get_iv_size($td);
        $iv = substr($data, 0, $ivsize);
        $data = substr($data, $ivsize);
        if ($iv)
        {
            mcrypt_generic_init($td, KEY, $iv);
            $data = mdecrypt_generic($td, $data);
        }
        return $data;
    }
    
    echo "<pre>";
    $data = md5('');
    echo "Data: $data\n";
    $e = encrypt($data);
    echo "Encrypted: $e\n";
    $d = decrypt($e);
    echo "Decrypted: $d\n";
    

    输出:

    Data: d41d8cd98f00b204e9800998ecf8427e
    Encrypted: ê÷#¯KžViiÖŠŒÆÜ,ÑFÕUW£´Œt?†÷>c×åóéè+„N
    Decrypted: d41d8cd98f00b204e9800998ecf8427e
    

    问题是,当我把encrypt函数放在传输文件(tx.php)中,而把decrypt函数放在接收文件(rx.php)中时,数据并没有完全解密(两个文件的key、cypher和mode的常量都相同)。

    Data before passing: a:4:{s:3:"err";i:1024;s:3:"msg";s:4:"Oops";s:4:"file";s:46:"/Applications/MAMP/htdocs/projects/txrx/tx.php";s:4:"line";i:80;}
    Data decrypted: Mª4:{s:3:"err";i:1024@7OYªç`^;g";s:4:"Oops";s:4:"file";sôÔ8F•Ópplications/MAMP/htdocs/projects/txrx/tx.php";s:4:"line";i:80;}
    

    我的卷发很简单:

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'data=' . $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);
    

    我怀疑是什么导致了这一切:

    • 与mcrypt填充缺少的字节有关
    • 我盯着它看了太久,错过了一些非常明显的东西

    如果我关闭crypt功能(因此传输tx->接收未加密)数据接收良好。

    谢谢,亚当

    3 回复  |  直到 16 年前
        1
  •  3
  •   ZZ Coder    16 年前

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'data=' . urlencode($data));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);
    
        2
  •  1
  •   Adam Hopkinson    16 年前

    我想出来了-不得不 base64_encode base64_decode 在解密之前。

    感谢那些为我着想的人!

        3
  •  1
  •   Elzo Valugi    15 年前

    这两个答案都不适合我。Base64\u编码仍然不安全,并且对于较长的字符串存在空格和加号问题。我发现 this 有帮助的功能:

    <?php 
    function urlsafe_b64encode($string)
    {
        $data = base64_encode($string);
        $data = str_replace(array('+','/','='),array('-','_','.'),$data);
        return $data;
    }
    function urlsafe_b64decode($string)
    {
        $data = str_replace(array('-','_','.'),array('+','/','='),$string);
        $mod4 = strlen($data) % 4;
        if ($mod4) {
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }
    ?>
    

    希望这能帮助别人。

    推荐文章