Encrypting files

S

SlimClity

I'm trying to encrypt file's using the Perl Crypt::Rijndeal module,
see encrypt.pl and decrypt.pl. Because the data must be in blocks of
16 I use "get16". Both scripts work, I can encrypt and decrypt files.
But the decrypted file is corrupt, eg. encrypt word file --> decrypt
--> File is corrupt.

I think this has something to do with the get16, when decrypting I
think I must remove those "\0" which were added (how??).... Or is it
something else??

-- encrypt.pl --
use Crypt::Rijndael;
$cipher = new Crypt::Rijndael "1234567890123456",
Crypt::Rijndael::MODE_CBC;

$srcfile = "doc.doc";
$destfile = "doc.enc";

#my ($srcfile, $destfile) = @_;
my $buffer;

open INF, $srcfile
or die "\nCan't open $srcfile for reading: $!\n";
open OUTF, ">$destfile"
or die "\nCan't open $destfile for writing: $!\n";

binmode INF;
binmode OUTF;

while (
read (INF, $buffer, 1024) # read in (up to) 64k chunks, write
and print OUTF $cipher->encrypt(get16($buffer)) # exit if read or
write fails
) {};
die "Problem copying: $!\n" if $!;

close OUTF
or die "Can't close $destfile: $!\n";
close INF
or die "Can't close $srcfile: $!\n";

sub get16 {
my $data = shift;
return "\0" x ( 16 - length($data)%16) . $data;
}
-- end of encrypt.pl --

-- decrypt.pl --
use Crypt::Rijndael;
$cipher = new Crypt::Rijndael "1234567890123456",
Crypt::Rijndael::MODE_CBC;

$srcfile = "doc.enc";
$destfile = "doc-new.doc";

#my ($srcfile, $destfile) = @_;
my $buffer;

open INF, $srcfile
or die "\nCan't open $srcfile for reading: $!\n";
open OUTF, ">$destfile"
or die "\nCan't open $destfile for writing: $!\n";

binmode INF;
binmode OUTF;

while (
read (INF, $buffer, 65536) # read in (up to) 64k chunks, write
and print OUTF $cipher->decrypt($buffer) # exit if read or write
fails
) {};
die "Problem copying: $!\n" if $!;

close OUTF
or die "Can't close $destfile: $!\n";
close INF
or die "Can't close $srcfile: $!\n";

sub get16 {
my $data = shift;
return "\0" x ( 16 - length($data)%16) . $data;
}
-- end of decrypt.pl --
 
J

Joe Smith

SlimClity said:
sub get16 {
my $data = shift;
return "\0" x ( 16 - length($data)%16) . $data;
}

What happens if $data is 1024 bytes long?
length($data) = 1024;
length($data)%16 = 0;
16 - length($data)%16 = 16;
return "\0" x 16 . $data; # Add corruption to every block read.

The nulls belong at the end, not the beginning, and there should
be 0 nulls, not 16, for full blocks.

-Joe
 
S

SlimClity

Joe Smith said:
What happens if $data is 1024 bytes long?
length($data) = 1024;
length($data)%16 = 0;
16 - length($data)%16 = 16;
return "\0" x 16 . $data; # Add corruption to every block read.

The nulls belong at the end, not the beginning, and there should
be 0 nulls, not 16, for full blocks.

Good point!
I've modified the get16:

sub get16 {
my $data = shift;
if (length($data)%16==0) {
$return = $data;
}
else {
$return = $data . "\0" x ( 16 - length($data) % 16 );
}
return $return;
}
 
S

SlimClity

I think this has something to do with the get16, when decrypting I
think I must remove those "\0" which were added (how??).... Or is it
something else??

Thanks for the help, I used the script from zentara and add the
modifiction from Joe. The script works now, but I only have one small
problem:

The script is part of a larger automated process. To make sure that
the encrypting and decrypting goes well we want to create an MD5
checksum before and after the encryption. This works if the original
file is in parts of 16. But when the file don't exists in parts of 16
then "0" are add to make the encryption work.

Now the MD5 chekcum is different...

Is there a way to solve is problem? Is it possible to remove the extra
"0" at the decrypting script? (How? regexp on the (binary) file??)
 
J

Joe Smith

SlimClity said:
The script is part of a larger automated process. To make sure that
the encrypting and decrypting goes well we want to create an MD5
checksum before and after the encryption. This works if the original
file is in parts of 16. But when the file don't exists in parts of 16
then "0" are add to make the encryption work.

You've discovered the difficulties of recovering raw data.

It would be better to put some structure in the encrypted file to
store metadata, like the size of the unencrypted file. I recommend
a file format that allows you to use "head -1 file.enc" to read the header.
You may have noticed that compressed files (*.Z and *.gz) have these
kinds of headers in the file.


In encrypt.pl, between "binmode OUTF;" and "while (", I would add

print OUT fileheader($srcfile);

so that there is enough information in the file for decrypt.pl to
recover the original file size.

use constant FORMAT => "SC/enc-1.0"; # SlimClity/encryption version 1.0

sub fileheader {
my $file = shift;
my ($mode,$size,$atime,$mtime) = (stat $file)[2,7,8,9];
my $header = sprintf "%s size=%d mode=%o time=%d access=%d name=%s\n",
FORMAT, $size, ($mode & 07777), $mtime, $atime, $file;
get16($header);
}

In decrypt.pl, you can use

open my $inf,$srcfile or die;
my ($size,$mode,$mtime,$atime,$destfile,$data) = get_fileheader($inf);
open my $outf,$destfile or die;
...
truncate $outf,$size or warn; # Remove any null padding
close $outf or die;
chmod $mode,$destfile or warn; # Restore file permissions
utime $atime,$mtime,$destfile or warn; # File access time and modify time
exit; # $inf gets closed automatically

use constant FORMAT => "SC/enc-1.0"; # SlimClity/encryption version 1.0

sub get_fileheader {
my $fh = shift;
my $buffer;
my $count = read($fg,$buffer,1024);
my ($header) = /^(.*?)\n/;
my ($format,$size,$mode,$atime,$mtime,$name) = $header =~
/(.*) size=(\d+) mode=(\d+) time=(\d+) access=(\d+) name=(.*)/;
die "Invalid file format '$header'\n" unless $format eq FORMAT;
$buffer = substr $buffer, length(get16($header));
($size,$mode,$mtime,$atime,$name,$buffer);
}



-Joe
 
S

SlimClity

The script is part of a larger automated process. To make sure that
the encrypting and decrypting goes well we want to create an MD5
checksum before and after the encryption. This works if the original
file is in parts of 16. But when the file don't exists in parts of 16
then "0" are add to make the encryption work.

Now the MD5 chekcum is different...

Thanks for the help zentera/Joe Smith!!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top