PHP: PEAR: encryption using Crypt_CBC, decryption using Perl CBC

One of the tasks I need to perform is to encrypt something from the PHP side and then decrypt it using Perl.

The PEAR module, which seems to suit my needs, was Crypt_CBC. However, there must be something that I am doing wrong or do not understand, because so far I have not been able to achieve the correct results.

The code snippets below are specifically designed for testing, since I wanted to try all this before applying it to my actual project code.

Firstly, here is my PHP code, with which I encrypt everything, is passed to the $ text parameter (i.e. 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; } 

From this point, I copy everything that is sent from this script (at the output of my browser) and paste it into the $ encrypted variable of my PERL script below:

 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; 

I tried a lot of things, for example, without pointing IV to the Perl side, etc., but it kept giving me errors all the time. This form is the only one with which I generally get output.

The result to accomplish the above, with the original $ text = "hello": Pñšîî7àÐŽZÊ & Rhello

What I find is that my source content is correctly decrypted, but not without adding a bunch of shitty characters in front of the part that I want.

Can someone point me to what I am doing wrong and how can I solve it?

Thanks a lot.

+3
source share
3 answers

CBC is not fault tolerant; a problem with the encryption text destroys the entire block. Thus, the fact that you can restore plain text with additional garbage suggests that the problem is with the padding, and not with the encryption itself.

Block cipher works with full blocks. If the last block is incomplete, it is supplemented in a way that allows the recipient to determine what the indentation is and what data. Find the API documentation to find out how indentation is handled.

If possible, convert the decrypted plaintext to hexadecimal and publish it so that non-printable bytes are visible. This may show the padding scheme used on the PHP side.

+4
source

I finally found a solution to my problem.

Thanks to all of you guys, your answers really helped. I followed your base64 encoding / decoding tips and therefore avoid encoding problems in text format.

What I had to do to make the decryption work, add 'header' => 'randomiv' to my Perl script cipher, since the PEAR Crypt_CBC class uses Random IV when encrypting.

I found this option in the Crypt :: CBC Documentation .

Also, looking directly at the CBC.php decryption function, I found what it did to determine IV: Take the length of the header ('RandomIV') and use it as an offset to fine-tune the encrypted string to the lock value (default is 8). I also indicated a key (56 by default) for a good measure.

For completeness and for reference, here are both of my updated test scripts:

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; 

There you go. Again, thank you very much!

Mathieu

+4
source

You should not do this with the simple output of your encryption procedure. You will probably encounter all coding issues. I suggest you base64-encode your encrypted string and copy and paste it, and then base64-decode it before decryption.

+3
source

All Articles