Subject: Strange key length behavior with Blowfish and CBC in Perl 5.8 on
To: None <netbsd-help@netbsd.org, lstein@cshl.org, amused@pobox.com>
From: Gan Uesli Starling <gan@starling.us>
List: netbsd-help
Date: 08/13/2005 14:55:31
This is a multi-part message in MIME format.
--------------000908070009020700010407
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
There is a mystery regarding 56- vs 112-byte keys in Blowfish
via Perl on NetBSD. I can't test it at present on Win32 as the
PPM server at Univ. Winnipeg seems to be down. Attached is
a short Perl script which exemplifies the mystery with an easy
toggle for both cases.
Affected NetBSD version is:
NetBSD 2.0.2 (GENERIC) #0: Wed Mar 23 08:53:42 UTC 2005
Affected Perl module packages are:
perl-5.8.6nb6 Practical Extraction and Report Language
p5-Crypt-Blowfish-2.09nb1
p5-Crypt-CBC-2.08nb1
Full details are embeded within the attached Perl script. Copy it to
anywhere, chmod it 755 and run it.
My question is whether this be a NetBSD package bug or a
Perl module bug or what?
Respectfully,
Gan Starling
Kalamazoo MI
--------------000908070009020700010407
Content-Type: application/x-perl;
name="gus_example_blowfish_cbc.pl"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="gus_example_blowfish_cbc.pl"
#!/usr/pkg/bin/perl -w
use Crypt::CBC;
my $double_key = 0; # Toggle 0 or 1 to see mystery behavior.
# Note 1: Blowfish algorithm claims 56 bytes for max key. But
# experimentation shows double (112) works with Blowfish alone.
# Likewise for minimal key, which Crypt::Blowfish says must be 8,
# but # really needs 16 for Blowfish alone. Yet here with Crypt::CBC
# alone, it goes back to requiring 56 and 8 rather than double. Why?
# Note 2: As regards Note 1 above, I can toggle the mysterious behavior
# back and forth by the either declaring 'use Crypt::Blowfish;' or not. Why?
# NetBSD uname -a says:
# NetBSD baal.amalekite.net 2.0.2 NetBSD 2.0.2 (GENERIC) #0: Wed Mar 23 08:53:42 UTC 2005 jmc@faith.netbsd.org:/home/builds/ab/netbsd-2-0-2-RELEASE/i386/200503220140Z-obj/home/builds/ab/netbsd-2-0-2-RELEASE/src/sys/arch/i386/compile/GENERIC i386
# NetBSD pkg_info says:
# perl-5.8.6nb6 Practical Extraction and Report Language
# p5-Crypt-Blowfish-2.09nb1 Perl5 Blowfish implementation
# p5-Crypt-CBC-2.08nb1 Perl5 cipher block chaining mode for various crypto algorithms
#############################
# BEGIN EXAMPLE PERL SCRIPT #
#############################
my $max_key_size = 56;
my $min_key_size = 8;
if ($double_key) {
use Crypt::Blowfish;
$max_key_size *= 2;
$min_key_size *= 2;
}
# Eight bytes minimum for cypher key!
my $key_text =
'Once upon a midnight dreary' .
'While I pondered weak and weary' .
'Over many a quaint and curious' .
'Volume of forgotten lore' .
'As I sat there nearly napping' .
'Suddenly there came a tapping' .
'As of someone gently rapping' .
'Rapping on my chamber door' .
'Merely this and nothing more';
# Uncomment line below to test for mininmal key.
# $key_text = substr($key_text, 0, $min_key_size); # See Note 1 above.
print "Key provided:\n\t", $key_text, "\n\n";
# Use the last, not first part, of key text.
my $key_0th = 0;
$key_0th = length($key_text) - $max_key_size if length($key_text) > $max_key_size;
$key_text = substr( $key_text, $key_0th);
print "Key portion used:\n\t", $key_text, "\n\n";
my $cipher = Crypt::CBC->new(
{ 'key' => $key_text,
'cipher' => 'Blowfish',
'iv' => '$KJh#(}q',
'regenerate_key' => 1, # default true
'padding' => 'space',
'prepend_iv' => 1
}
);
# Prepare to encrypt this very Perl script.
open(FILE_AU,"<./gus_example_blowfish_cbc.pl"); # Golden original.
open(FILE_PB,">./gus_example_blowfish_cbc.cfr"); # Leaden copy.
# Encrypt it now.
$cipher->start('encrypting');
print FILE_PB $cipher->crypt($_) while <FILE_AU>;
print FILE_PB $cipher->finish();
# Prepare to decrypt it back again.
open(FILE_PB,"<./gus_example_blowfish_cbc.cfr"); # Leaden copy.
open(FILE_AG,">./gus_example_blowfish_cbc.pln"); # Silver copy.
# Decrypt it now.
$cipher->start('decrypting');
print FILE_AG $cipher->crypt($_) while <FILE_PB>;
print FILE_AG $cipher->finish();
# Compare golden versus silver via Unix 'diff' functioin.
# So must test to skip when on Win32 systems.
unless ( $^O =~ /Win/i) {
print "Differences before/after encryption:\n\t";
my $differences = join "\n\t", `diff gus_example_blowfish_cbc.pl gus_example_blowfish_cbc.pln`;
print $differences, "\n";
print "Total of differing lines: ", length $differences, "\n\n";
}
# Let user know this script did not hang.
print "All done.\n";
--------------000908070009020700010407--