PHP: PEAR: шифрование с помощью Crypt_CBC, дешифрование с помощью Perl CBC - PullRequest
4 голосов
/ 17 марта 2009

Одна из задач, которую я должен выполнить, заключается в том, чтобы я зашифровал что-то со стороны PHP, а затем расшифровал это с помощью Perl.

Модуль PEAR , который я нашел и который подходит для моих нужд, был Crypt_CBC. Однако должно быть что-то, что я делаю неправильно или не понимаю, так как до сих пор не смог добиться правильных результатов.

Приведенные ниже выдержки из кода специально предназначены для целей тестирования, так как я хотел все это попробовать, прежде чем применять его к коду моего реального проекта.

Во-первых, вот мой PHP-код, с помощью которого я шифрую все, что передается параметру $ text (т.е. cryptTest.php? Text = hello)

require_once('Crypt/CBC.php');  

$key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE";  
$cipher = new Crypt_CBC($key, 'BLOWFISH');

$encrypted = $cipher->encrypt($text);  

if (PEAR::isError($encrypted)) {  
    echo $encrypted->getMessage();  
} else {  
    echo "ENCRYPTED STRING: " . $encrypted;  
}  

С этого момента я копирую все, что отражено в этом скрипте (в выводе моего браузера), и вставляю его в переменную $ encrypted моего скрипта PERL ниже:

use Crypt::CBC; 
$encrypted = "RandomIVá´bp3Ó¯làK”Á(Û";  
my $key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE";  
my $vector = "\0\0\0\0\0\0\0\0";  

my $cipher = Crypt::CBC->new(  
                       {'key'             =>$key,  
                        'cipher'          => 'Blowfish',  
                        'iv'              => $vector,  
                        'prepend_iv'      => 0  
                       });  

my $plaintext = $cipher->decrypt($encrypted);

print $plaintext;

Я пробовал много вещей, например, не указывал IV на стороне Perl и тому подобное, но он продолжал давать мне ошибки. Эта форма единственная, с которой я получаю какие-либо результаты вообще.

Результат выполнения вышеизложенного с исходным $ text = "hello": Pñšîî7àÐŽZÊ & Rhello

Что я обнаружил, так это то, что мой исходный контент правильно расшифровывается, но не без добавления группы дерьмовых символов перед нужной мне частью.

Может кто-нибудь указать мне на то, что я делаю неправильно, и как я могу это исправить?

Спасибо большое.

Ответы [ 3 ]

5 голосов
/ 18 марта 2009

Я наконец нашел решение своей проблемы.

Спасибо вам обоим, ваши ответы помогли. Я следовал вашему совету кодировать / декодировать в base64 и, следовательно, избегать любых проблем с кодировкой простого текста.

То, что мне нужно было сделать для дешифрования, это добавить 'header' => 'randomiv' к созданию моего шифра Perl-скрипта, поскольку класс Crypt_CBC в PEAR использует Random IV при шифровании. 1007 *

Я нашел этот конкретный параметр в документации Crypt :: CBC .

Кроме того, заглянув непосредственно в функцию расшифровки CBC.php, я обнаружил, что она сделала для определения IV: взять длину заголовка ('RandomIV') и использовать ее в качестве смещения для подстановки зашифрованной строки до Значение blocksize (по умолчанию 8). Я также указал размер ключа (56 по умолчанию) для хорошей меры.

Для полноты и справки, вот оба моих обновленных сценария тестирования:

PHP (cryptTest.php):

require_once('Crypt/CBC.php');

$key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE";  
$cipher = new Crypt_CBC($key, 'BLOWFISH');

$encrypted = $cipher->encrypt($text);

if (PEAR::isError($encrypted)) {  
    echo $encrypted->getMessage();  
} else {  
    echo "ENCRYPTED STRING: " . base64_encode($encrypted);  
}

PERL (decryptTest.pl)

use Crypt::CBC;  
use MIME::Base64;

my $encrypted = decode_base64("UmFuZG9tSVbrNE3ony00FlUbiprLn0fu");  
my $key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE";  
my $header_spec = "randomiv";  
my $blocksize = 8;  
my $keysize = 56;  

my $iv_offset = length $header_spec;  
my $iv = substr $encrypted, $iv_offset, $blocksize;

my $cipher = Crypt::CBC->new(  
                {'key'        =>$key,  
                'cipher'        => 'Blowfish',  
                'iv'            => $iv,  
                'header'        => $header_spec,  
                'prepend_iv'    => $iv_offset,  
                'blocksize'  => $blocksize,  
                'keysize'      => $keysize   
                })  

my $plaintext = $cipher->decrypt($encrypted);

print $plaintext;

Вот, пожалуйста. Еще раз большое спасибо!

Матье

4 голосов
/ 17 марта 2009

CBC не отказоустойчив; проблема с зашифрованным текстом разрушает весь блок. Итак, тот факт, что вы можете восстановить обычный текст с дополнительным мусором, говорит о том, что проблема заключается в заполнении, а не в самом шифровании.

Блочный шифр работает на полных блоках. Если последний блок является неполным, он дополняется таким образом, чтобы получатель мог определить, что такое заполнение и что такое данные. Найдите документацию API, чтобы узнать, как обрабатывается заполнение.

Если возможно, преобразуйте дешифрованный открытый текст в шестнадцатеричный и разместите его так, чтобы непечатные байты были видны. Это может раскрыть схему заполнения, используемую на стороне PHP.

3 голосов
/ 18 марта 2009

Вы не должны делать это с простым выводом вашей процедуры шифрования. Вы, вероятно, столкнетесь со всевозможными проблемами кодирования. Я предлагаю вам base64-кодировать вашу зашифрованную строку, скопировать и вставить ее, а затем base64-декодировать перед расшифровкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...