使用 mcrypt 通过 Web 服务传递数据失败
我正在编写一个错误处理程序脚本,它对错误数据(文件、行、错误、消息等)进行加密,并将序列化数组作为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
加密的数据是二进制的,但您没有对其进行 URL 编码。在 CURL 中执行此操作,
The encrypted data is binary but you didn't URL encoded it. Do this in the CURL,
我想通了 - 必须在加密后对数据进行
base64_encode
,然后在解密之前对数据进行base64_decode
。感谢那些为我出谋划策的人!
I figured it out - had to
base64_encode
the data after encryption and thenbase64_decode
before decrypting.Thanks to those who had a think on my behalf!
这个答案对我来说都不好。 Base64_encode 仍然不安全,并且存在较长字符串的空格和加号问题。我发现这个功能很有帮助:
希望这对某人有帮助。
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:
Hope this helps somebody.