views:

1029

answers:

4

A file has been encrypted by Perl. Initial decrypt attempts failed and I am now trying to ascertain whether there is any hoojoo going on (some other settings required)

Duff Perl Code:

use strict;

use Crypt::Rijndael;

my $key ='...';

my $rcipher = Crypt::Rijndael->new ($key, Crypt::Rijndael::MODE_CBC());

undef $/;
my $encrypted = <>;

print $rcipher->decrypt($encrypted);

C# Decryption Implementation

        CryptoStream decryptor = null;
        StreamReader srDecrypt = null;
        FileStream fsIn = null;
        RijndaelManaged rijndaelCipher = null;
        string fileContents;
        try
        {
            rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Key = Encoding.UTF8.GetBytes(Password);
            rijndaelCipher.IV = Encoding.UTF8.GetBytes(Password);
            rijndaelCipher.Padding = PaddingMode.None;

            fsIn = new FileStream(FilePath, FileMode.Open);
            decryptor = new CryptoStream(fsIn, rijndaelCipher.CreateDecryptor(), CryptoStreamMode.Read);
            srDecrypt = new StreamReader(decryptor);
            fileContents = srDecrypt.ReadToEnd();
        }
        finally
        {
            if (decryptor != null)
                decryptor.Close();
            if (fsIn != null)
                fsIn.Close();
            if (srDecrypt != null)
                srDecrypt.Close();

            if (rijndaelCipher != null)
                rijndaelCipher.Clear();
        }

How Perl Code should read

binmode OUTF;

my $key ="..."; # Your secret key

my $rcipher = Crypt::Rijndael->new ($key, Crypt::Rijndael::MODE_CBC());

$rcipher->set_iv($key); # You may wish this IV to be something different from the Secret Key

my $plaintext = "Please encrypt me"; # Your string to be encrypted

if(length($plaintext) % 16 != 0 ) {

$plaintext .= ' ' x (16 - (length($plaintext) % 16)); } 

my $rencrypted = $rcipher->encrypt($plaintext);
+4  A: 

I'm assuming you run this on Windows. You're dealing with binary data, so you need to take that into account. In Perl, you have to use binmode. I think you need to use BinaryReader in C# (but I'm no C# programmer, so I'm not sure).

Leon Timmermans
+2  A: 

Have you tried encrypting / decrypting a simple string? With that you could verify that the there is something from in the encryption (and not with reading the file).

Bart S.
+4  A: 

Have you got the same IV sizes? I'm asking as I've had similar problems with Perl to C# encryption conversion, where the IV size was different in Perl.

Your KeySize is 256 (bits) but the key you have in the Perl code is 3 bytes, 12 bits which if I remember Perl pads it with white space.

Chris S
+11  A: 

I'm the maintainer of Perl's Crypt::Rijndael. I didn't write the original code, but I try to make it work when it fails for other people.

I received another report like this as RT #27632. The problem in the module was a signed int that should have been an unsigned int. The latest version of Crypt::Rijndael, 1.07, should have the fix. Which version are you using?

Also, some of these problems are platform dependent. If you look in the rijndael.h code in the distribution, you'll see the hoops I have to jump through to get the right type sizes for various platforms. I figure you're on Windows (but not Cygwin). Which version of Windows are you using?

As noted in the RT ticket, the first step is to encrypt the same messages with the same initialization vectors using both Crypt::Rijndael and the C# implementation. You should get the same output. If you don't get the same crypttext, there is a problem.

Let me know how this works out for you so I can track it as a Crypt::Rijndael bug if I need to.

Thanks,

brian d foy
Hi Brian, Thanks for the post. FYI we are Windows Server 2008 (and 2003) / .Net Framework 3.5 / X64.
David Christiansen