Using mcrypt to pass data across a webservice is failing

孤街浪徒 提交于 2020-01-04 15:28:43

问题


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


回答1:


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



回答2:


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!




回答3:


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.



来源:https://stackoverflow.com/questions/2746939/using-mcrypt-to-pass-data-across-a-webservice-is-failing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!