11 Dec 2011

Encoding files "on the fly" with Blowfish using Perl

Some time ago friend of mine asked me if I could write him an CGI script which encodes his backup file and allows to download it using HTTP protocol.

He is using some kind of VPS so my CGI app had some limitations:

  • file must be encoded "on the fly" to save disk space (no temporary files)
  • encoding should be memmory efficient - because VPS hasn't got very much RAM and backup files are quite large
  • encoding should be fast - so the best solution would be using XS module

After some research I've created this two scripts:

Warning: Scripts depends on external Perl modules which are available at CPAN and in Debian repository.
apt-get install libcrypt-cbc-perl libcrypt-blowfish-perl

Blowfish CGI encoding using Perl

#!/usr/bin/perl

use strict;
use warnings;

use CGI;
use HTML::Entities;
use Crypt::CBC;
use File::Spec;

my $as_cgi = 1; # if run from apachce set to 1 if CLI 0

my $key = "ala_ma_kota.123";
my $fName = './large_file.bin';

my $chunkSize = 1024;
my $out_FName = 'out.bin';



if ( $as_cgi ) {
 print "Content-Type:application/octet-stream; name=\"".$out_FName."\"\r\n";
 print "Content-Disposition: attachment; filename=\"".$out_FName."\"\r\n\n";
}

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

die "Unable to find file $fName\n" if not -e $fName;


open(ENCODEME, '<:raw', $fName) or die "$!";
binmode ENCODEME;
$cipher->start('encrypting');
while( read(ENCODEME,$buffer,$chunkSize) ) {
 print $cipher->crypt($buffer);
}
print $cipher->finish;
close(ENCODEME);

Blowfish decoding file using Perl

 #!/usr/bin/perl

# apt-get install libcrypt-cbc-perl
# apt-get install libcrypt-blowfish-perl

use strict;
use warnings;

use Crypt::CBC;
use File::Spec;

my $key = "ala_ma_kota.123";
my $chunkSize = 1024;

my $fName = 'zz.bin';

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

#$fName = File::Spec->catfile($base_dir, $fName);
die "Unable to find file $fName\n" if not -e $fName;


open(ENCODEME, '<:raw', $fName) or die "$!";
binmode ENCODEME;
$cipher->start('decrypting');
while( read(ENCODEME,$buffer,$chunkSize) ) {
 print $cipher->crypt($buffer);
}
print $cipher->finish;
close(ENCODEME);

No comments:

Post a Comment