views:

204

answers:

2

Good day! I have a code here that uses the blowfish_PP algorithm from Crypt::Blowfish_PP to encrypt a password.

I've provided a sample "key" variable for a start (though I will make a function later that will increment key every time I use it), but for now this is what I've got:

use Crypt::Blowfish_PP;

$key = "12345678";
$$plaintextBlock = "mystringhere";

$blowfish=new Crypt::Blowfish_PP($key);

$ciphertextBlock=$blowfish->encrypt($plaintextBlock);

$plaintextBlock=$blowfish->decrypt($ciphertextBlock);

print "\n";
print $ciphertextBlock."\n";
print $plaintextBlock."\n";

This $ciphertextBlock outputs ONLY 5 characters. When I checked the encryptedpassword of other DB using MD5, it contains several characters. Why is that? What is inside encrypt() and decrypt() functions? Does the "key" value matters on how long the encrypted password will be?

Answers will be much appreciated. =)

+3  A: 

According to Blowfish_PP documentation, encrypt and decrypt only work on single 8-byte block at a time. So if you are encrypting longer strings, you need to call encrypt repeatedly.

Why it only outputs 5 "characters" is probably because the ciphertext contains non-printable characters. If you want to print the data, convert it to e.g. hex ascii first:

print sprintf("%02x"x8, unpack("C8", $ciphertextBlock)), "\n";
laalto
+2  A: 

As laalto said, Blowfish_PP (because it's Blowfish, not because it's _PP) is working on blocks.

Dealing with it is usually complex, that's why you have Crypt::CBC module which is a wrapper on (virtually) any Crypt::* module that provides block cipher, and allows you to use it in a much simpler way.

For example, your code with Crypt::CBC would be:

#!/usr/bin/perl -w
use strict;
use Crypt::CBC;

my $key = "12345678";
my $plaintextBlock = "mystringhere";

my $cipher = Crypt::CBC->new(
    -key    => $key,
    -cipher => 'Blowfish_PP'
);

my $ciphertext = $cipher->encrypt($plaintextBlock);
# my $textual = $ciphertext;
# $textual =~ s/([^a-zA-Z0-9])/sprintf "\\x%02x", ord $1/ge;
# print "ciphertext: [$textual]\n";
print "ciphertext: [$ciphertext]\n";

my $plaintext  = $cipher->decrypt($ciphertext);
print "plaintext: [$plaintext]\n";

Remember that ciphertext is stream of bytes, so it's not really printable. You might want to unhash 3 lines in the code (starting with my $textual = $ciphertext) to show the ciphertext in a bit more readable way.

Additional benefit of using Crypt::CBC is that if you'll ever want to switch to another algorithm - it's just one change in Crypt::CBC->new() call.

By the way - why Crypt::Blowfish_PP ? I mean, why not Crypt::Blowfish? _PP version is generally simply slower.

Additional note, straight from Crypt::Blowfish, which we can assume to be functionally equivalent to Crypt::Blowfish_PP:

The module is capable of being used with Crypt::CBC. You’re encouraged to read the perldoc for Crypt::CBC if you intend to use this module for Cipher Block Chaining modes. In fact, if you have any intentions of encrypting more than eight bytes of data with this, or any other block cipher, you’re going to need some type of block chaining help. Crypt::CBC tends to be very good at this. If you’re not going to encrypt more than eight bytes, your data must be exactly eight bytes long. If need be, do your own padding. "\0" as a null byte is perfectly valid to use for this.

depesz