1
votes

I am trying to encrypt a file in C# and decrypt the content in delphi as a string. I have tried several settings, key/block sizes and modes. Currently the code on C# side is:

private void EncryptFile(string inputFile, string keyCode, string outputFile)
{
    try         {   
        byte[] key = Encoding.Unicode.GetBytes(keyCode);
        byte[] iv = new byte[16];
        Array.Copy(key, iv, 16);

        FileStream fsCrypt = new FileStream(outputFile, FileMode.Create);

        var RMCrypto = new AesManaged();
        RMCrypto.KeySize = 256;
        RMCrypto.BlockSize = 128;
        RMCrypto.Mode = CipherMode.ECB;

        CryptoStream cs = new CryptoStream(fsCrypt,
                                           RMCrypto.CreateEncryptor(key, iv),
                                           CryptoStreamMode.Write);

        FileStream fsIn = new FileStream(inputFile, FileMode.Open);

        int data;
        while ((data = fsIn.ReadByte()) != -1)
            cs.WriteByte((byte)data);
            
        fsIn.Close();
        cs.Close();
        fsCrypt.Close();
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
    }
}

The key parameter is a C# string "1234567887654321". And the reverse part in delphi using the DEC library looks like that:

    procedure TForm1.Button1Click(Sender: TObject);

var
  RCipher: TCipher_Rijndael;
  FileStream: TFileStream;
  StringStream: TStringStream;
  StringBytes: TBytes;
  Key: String;

begin

  Key := '1234567887654321';

  StringBytes := TEncoding.Unicode.GetBytes(Key);

  RCipher := TCipher_Rijndael.Create();
  FileStream := TFileStream.Create('C:\path\to\file.txt', fmOpenRead);

  StringStream := TStringStream.Create('', TEncoding.ANSI);

  RCipher.Init(StringBytes[0], 32, StringBytes[0], 16);
  RCipher.Mode := cmECBx;
  RCipher.DecodeStream(FileStream, StringStream, FileStream.Size);

  Memo1.Text := StringStream.DataString;

  RCipher.Free;
  FileStream.Free;
  StringStream.Free;

end;

but all i get is random characters... where could be the problem? Are the algorithms incompatible with each other?

EDIT: Replaced term 'chinese characters' by 'random characters' to avoid confusion with unicode issues.

Thanks to pf1957 the solution was unexpected yet simple. I was using the Delphi Encryption Compendium library 5.1 which was obviously not AEC compliant. After i upgraded the code to the DEC 5.2 library all worked fine.

1
Have you tried RijndaelManaged instead of AESManaged? Here's a link. - Davin Tryon
Looks like unicode ansi mismatch - David Heffernan
Yes, that was my first choice... But i got the same problems. Then i read that the AesManaged is compliant to the AES standard and i thought its better to go with that, as its more likely that the delphi library also implements the AES standard. - thalm
@thalm: Is C:\path\to\file.txt correct name for you encrypted output? I do not see a reason, why it should not work. I've tested your code using VS10+SP1 and .NET 4 against Delphi XE3+SP1 using DEC 5.2 (with minor fix in ModuleUnload signature) and it works for me - pf1957
@thalm: thanx, everybody who will need it can find answer in your edited question and me, I'm not a collector ;) - pf1957

1 Answers

-1
votes

You are using 16 byte (128-bit) key data, while you are setting encryptor/decryptor to use 256-bit key.

So, after you'll fix the usage of TStringStream (never use it with binary data), check code or documentation for both libraries to know what is done with key data - most likely it is not used directly as key but used as 'password' for key derivation process.