使用 mcrypt 通过 Web 服务传递数据失败

发布于 2024-08-30 13:30:58 字数 2078 浏览 6 评论 0原文

我正在编写一个错误处理程序脚本,它对错误数据(文件、行、错误、消息等)进行加密,并将序列化数组作为 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

问题是,当我将加密函数放入我的传输文件(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;}

注意中间的随机字符。

我的curl相当简单:

$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 未加密),则数据接收良好。

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

谢谢,亚当

I'm writing an error handler script which encrypts the error data (file, line, error, message etc) and passes the serialized array as a POST variable (using curl) to a script which then logs the error in a central db.

I've tested my encrypt/decrypt functions in a single file and the data is encrypted and decrypted fine:

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

Output:

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

The problem is, when I put the encrypt function in my transmit file (tx.php) and the decrypt in my recieve file (rx.php), the data is not fully decrypted (both files have the same set of constants for key, cypher and 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;}

Note the random characters in the middle.

My curl is fairly simple:

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

Things I suspect could be causing this:

  • Encoding of the curl request
  • Something to do with mcrypt padding missing bytes
  • I've been staring at it too long and have missed something really really obvious

If I turn off the crypt functions (so the transfer tx->rx is unencrypted) the data is received fine.

Any and all help much appreciated!

Thanks, Adam

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

听不够的曲调 2024-09-06 13:30:58

加密的数据是二进制的,但您没有对其进行 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);

The encrypted data is binary but you didn't URL encoded it. Do this in the 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);
七度光 2024-09-06 13:30:58

我想通了 - 必须在加密后对数据进行 base64_encode ,然后在解密之前对数据进行 base64_decode

感谢那些为我出谋划策的人!

I figured it out - had to base64_encode the data after encryption and then base64_decode before decrypting.

Thanks to those who had a think on my behalf!

心房敞 2024-09-06 13:30:58

这个答案对我来说都不好。 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);
}
?>

希望这对某人有帮助。

Neither this answers were ok for me. Base64_encode is still not safe and has issues with spaces and plus signs for longer strings. I found this functions helpful:

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

Hope this helps somebody.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文