2

我正在编写一个错误处理程序脚本,它加密错误数据(文件、行、错误、消息等)并将序列化数组作为 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?†÷&gt;c×åóéè+„N
Decrypted: d41d8cd98f00b204e9800998ecf8427e

问题是,当我将加密函数放在我的传输文件(tx.php)中并在我的接收文件(rx.php)中解密时,数据没有完全解密(两个文件具有相同的密钥常量集,密码和模式)。

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

我怀疑可能导致这种情况的事情:

  • curl请求的编码
  • 与 mcrypt 填充缺失字节有关
  • 我一直盯着它太久了,错过了一些非常明显的东西

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

非常感谢任何和所有帮助!

谢谢,亚当

4

3 回答 3

3

加密数据是二进制的,但您没有对其进行 URL 编码。在 CURL 中执行此操作,

$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);
于 2010-04-30T19:15:38.987 回答
1

我想通了 - 必须base64_encode加密后和base64_decode解密前的数据。

感谢那些代表我思考的人!

于 2010-04-30T19:44:15.547 回答
1

这两个答案对我来说都不好。Base64_encode 仍然不安全,并且对于较长的字符串存在空格和加号问题。我发现这个功能很有帮助:

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

希望这可以帮助某人。

于 2010-10-29T12:45:04.050 回答