Использование mcrypt для передачи данных через веб-сервис не работает - PullRequest
2 голосов
/ 30 апреля 2010

Я пишу скрипт обработчика ошибок, который шифрует данные об ошибках (файл, строка, ошибка, сообщение и т. Д.) И передает сериализованный массив как переменную 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;}

Обратите внимание на случайные символы в середине.

Мой локон довольно прост:

$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
  • Я слишком долго смотрел на это и упустил что-то действительно очевидное

Если я отключаю функции шифрования (чтобы передача tx-> rx была незашифрованной), данные получаются нормально.

Любая помощь очень ценится!

Спасибо, Адам

Ответы [ 3 ]

3 голосов
/ 30 апреля 2010

Зашифрованные данные являются двоичными, но вы их не закодировали. Сделай это в 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);
1 голос
/ 29 октября 2010

Ни один из этих ответов не был в порядке для меня. 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);
}
?>

Надеюсь, это кому-нибудь поможет.

1 голос
/ 30 апреля 2010

Я понял - пришлось base64_encode данные после шифрования и затем base64_decode перед расшифровкой.

Спасибо тем, кто задумался от моего имени!

...