Gossamer Forum
Home : General : Perl Programming :

Blowfish (am I stupid?)

Quote Reply
Blowfish (am I stupid?)
I've been monkeying around with Blowfish and have gotten it to work with one exception.

This works:

Code:
#!/usr/local/bin/perl

use Crypt::Blowfish;


my $key = pack("H16", "0123456789ABCDEF"); # min. 8 bytes
my $cipher = new Crypt::Blowfish $key;
my $ciphertext = $cipher->encrypt("big John"); # SEE NOTES
my $plaintext = $cipher->decrypt($ciphertext);


print "Content-type: text/html\n\n";
print "<html>\n <head>\n <title></title>\n </head>\n";
print "<body>\n <center>\n <h1>Here You Go</h1>\n </center>\n";
print unpack("H32", $ciphertext), "\n";
print "<P> $plaintext";
print "</body>\n</html>\n";

When executed it gives you the encrypted part and the decrypted part.

Now... if the encrypted word (Big John) is more than 8 characters long then the script breaks (server error). Wha' hoppen?

Does anybody know of a good tutorial on Blowfish or any other related encryption programs?
Quote Reply
Re: [Watts] Blowfish (am I stupid?) In reply to
Check out the documentation at http://search.cpan.org/~dparis/Crypt-Blowfish-2.10/Blowfish.pm

encrypt
Quote:
"This function encrypts $plaintext and returns the $ciphertext where $plaintext and $ciphertext must be of blocksize() bytes. (hint: Blowfish is an 8 byte block cipher)"



Notice something important with the following:
Code:
use Crypt::Blowfish;
$key = pack ('H16', '0123456789ABCDEF');
$crypt = Crypt::Blowfish -> new ($key);
sub out {
s/(.)/sprintf ('%02X', ord ($1))/esg foreach (@_);
local $" = $/;
print "@_$/";
}
out (
$crypt -> encrypt ('Big John'),
$crypt -> encrypt ('TallJohn'),
$crypt -> encrypt ('SmallJon')
);




You should get:
Quote:

86049CA9BF0F3030
4B79E3794F90C936
C4BB958DD965F4A6



Notice that they are all the same size? Try using something like this:

Code:
sub encrypt ($$) {
my $blow = shift; # the blowfish object
my $text = shift;
# pad your text to the right length - this is simple, but not necessarily the best option
$text .= chr (0) x (length ($text) % 8); # x is higher presidence than %
my @crypt = $text =~ /(.{8})/g; # split the text into pairs of 8
my $result = '';
foreach (@crypt) { # for clarity versus the one liner
$result .= $blow -> encrypt ($_);
}
return $result;
}

sub decrypt ($$) {
my $blow = shift;
my @crypt = $_[0] =~ /(.{8})/g;
my $result = '';
foreach (@crypt) {
$result .= $blow -> decrypt ($_);
}
$result =~ s/\0+$//sg;
return $result;
}

...
print +decrypt ($crypt, encrypt ($crypt, 'It is mostly true that this statement is false.')), $/; # len % 8 == 1





That's a pretty easy way to do it. You could write your own module to implement this simply.

Code:
package MyBetterBlowfish;
use base 'Crypt::Blowfish';
# copy the above subs here, changing their names
...
package main;
my $crypt = new MyBetterBlowfish $key; # then change all occurences of Crypt::Blowfish, encrypt, and decrypt



Or you could do something like
Code:
sub Crypt::Blowfish::myencrypt ($$) {
# sub above goes here...
}


or
Code:
package Crypt::Blowfish;
sub myencrypt ...





And you should probably use a fairly simple way to obfuscate the output (scrambling input, output, and the order of the pairs, for example). This reduces what someone knows about the original text assuming they know your key but not the way you rearranged stuff (of course you'd have to rerearrange the stuff so its in the right order in your decrypt function).
Quote Reply
Re: [mkp] Blowfish (am I stupid?) In reply to
Thanks for the help & the link. I'll give it a go and let you know what comes out.
Quote Reply
Re: [Watts] Blowfish (am I stupid?) In reply to
Follow up:

Here are two working examples someone came up with. I think I'll hack the Blowfish one for my use.

http://www.infocopter.com/perl_corner/crypt-cbc.htm#BLOWFISH

I was able to get both of these examples to work on a shared server hosted by hostcentric (ie, modules were already installed, etc.) without a whole lot of fuss.
They seem to provide just what I needed, on-the-fly encryption as part of a larger script. No "state secrets" or even credit card #'s here, just standard information you don't want the average-joe stumbling across.