I'm trying to encrypt a text file using Perl and then decrypt it using a different application written in C#. Here's my Perl code:
use strict;
use Crypt::CBC;
my $ifh;
my $ofh;
my $line;
my $cipher = Crypt::CBC->new(
{
'key' => 'length16length16',
'cipher' => 'Rijndael',
'iv' => 'length16length16',
'literal_key' => 1,
'header' => 'none',
'padding' => 'null',
'keysize' => 128 / 8
}
);
open($ifh,'<', $infile)
or die "Can't open $infile for encryption input: $!\n";
open($ofh, '>', $outfile)
or die "Can't open $outfile for encryption output: $!\n";
$cipher->start('encrypting');
for $line (<$ifh>) {
print $ofh $cipher->crypt($line);
}
print $ofh $cipher->finish;
close($ifh)
or die "Error closing input file: $!\n";
close($ofh)
or die "Error closing output file: $!\n";
And my C# code for decryption:
RijndaelManaged myRijndael = new System.Security.Cryptography.RijndaelManaged();
myRijndael.Key = System.Text.Encoding.UTF8.GetBytes("length16length16");
myRijndael.IV = System.Text.Encoding.UTF8->GetBytes("length16length16");
myRijndael.Mode = CipherMode.CBC;
myRijndael.Padding = PaddingMode.None;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = myRijndael.CreateDecryptor(myRijndael.Key, myRijndael.IV);
//Create the streams used for decryption.
FileStream file = File.OpenRead(strInFile);
CryptoStream csDecrypt = new CryptoStream(file, decryptor, CryptoStreamMode.Read);
StreamReader srDecrypt = new StreamReader(csDecrypt);
// Read the decrypted bytes from the decrypting stream
string decryptedText = srDecrypt.ReadToEnd();
I keep getting
System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid
When I try to read the data a few bytes at a time, I notice that the first 100 or so bytes are decrypted properly, but the rest is just garbage.
BTW, I can decrypt the encrypted file using Perl with:
$cipher->start('decrypting');
So what am I doing wrong with C# and Perl?
EDIT: I tried following @munissor advice and change the C# code to use
PaddingMode.Zeros
but I still get the same exception. Help please...
Found the solution!!!
In Perl, I had to add after the opening of the output file:
binmode $ofh;
The padding suggestion was helpful, but in the end I omitted the padding directive and used the default which is PKCS7 in Perl and in C#.
My final Perl code looks like this:
use strict;
use Crypt::CBC;
my $ifh;
my $ofh;
my $cipher = Crypt::CBC->new(
{
'key' => 'length16length16',
'cipher' => 'Rijndael',
'iv' => 'length16length16',
'literal_key' => 1,
'header' => 'none',
'keysize' => 128 / 8
}
);
#open input and output file
open($ifh,'<', $infile)
or die "Can't open $infile for encryption input: $!\n";
open($ofh, '>', $outfile)
or die "Can't open $outfile for encryption output: $!\n";
binmode &ofh;
$cipher->start('encrypting');
#write encrypted data to output file
while (read($ifh,my $buffer,1024))
{
print $ofh $cipher->crypt($buffer);
}
print $ofh $cipher->finish;
#close file handles
close($ifh)
or die "Error closing input file: $!\n";
close($ofh)
or die "Error closing output file: $!\n";
and the C# part:
RijndaelManaged myRijndael = new System.Security.Cryptography.RijndaelManaged();
myRijndael.Key = System.Text.Encoding.UTF8.GetBytes("length16length16");
myRijndael.IV = System.Text.Encoding.UTF8->GetBytes("length16length16");
myRijndael.Mode = CipherMode.CBC;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = myRijndael.CreateDecryptor(myRijndael.Key, myRijndael.IV);
//Create the streams used for decryption.
FileStream file = File.OpenRead(strInFile);
CryptoStream csDecrypt = new CryptoStream(file, decryptor, CryptoStreamMode.Read);
StreamReader srDecrypt = new StreamReader(csDecrypt);
// Read the decrypted bytes from the decrypting stream
string decryptedText = srDecrypt.ReadToEnd();