(I tried asking this on Cryptography Stack Exchange and they didn't feel it was appropriate there.)
I'm trying to replicate an algorithm written in Delphi in C#, preferably using the standard .NET libraries. Supposedly the Delphi algorithm passes standard reference tests. It's supposed to be AES/CBC; however, I've been unable to duplicate the results with System.Security.Cryptography.AesManaged.
Example of calling it with simple input:
function StringToHex(S: string): string;
var
  i: integer;
begin
  Result := '';
  for i := 1 to Length(S) do
    Result := Result + IntToHex(Ord(S[i]), 2);
end;
var
  PlainText:     AnsiString;
  AES:           TAES;
  Key:           TAESKey256;  // array[0..31] of byte;
  InitialVector: TAESBuffer;  // array[0..15] of byte;
  InputStream:   TStringStream;
  OutputStream:  TStringStream;
begin
  PlainText := 'test';
  FillChar(Key, SizeOf(Key), 1);
  FillChar(InitialVector, SizeOf(InitialVector), 2);
  AES          := TAES.Create;
  InputStream  := TStringStream.Create(PlainText);
  OutputStream := TStringStream.Create('');
  try
    AES.EncryptAESStreamCBC(InputStream, 0, Key, InitialVector, OutputStream);
    Writeln(StringToHex(OutputStream.DataString));
    Readln;
  finally
    InputStream.Free;
    OutputStream.Free;
    AES.Free;
  end;
end.
Output:
CEE3684F05D02E5A0930CED21F76075A
The code appears to have been based on the Delphi Spring Framework.
How can I replicate this in .NET?
What I've tried (even switching to bytes to avoid any Unicode issues):
public byte[] Encrypt()
{
    using (var algorithm = new AesManaged())
    {
        // Default is CBC
        algorithm.Key = Enumerable.Repeat((byte)0x01, 32).ToArray();
        algorithm.IV = Enumerable.Repeat((byte)0x02, 16).ToArray();
        using (ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV))
        {
            using (var stream = new MemoryStream())
            {
                using (var cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
                {
                    using (var writer = new BinaryWriter(cryptoStream))
                    {
                        writer.Write(new byte[] {0x74, 0x65, 0x73, 0x74});
                    }
                    return stream.ToArray();
                }
            }
        }
    }
}
This results in different output, though (the first byte is x6D).
In other task guy mentioned default settings for c#:
BlockSize = 128;
Mode = System.Security.Cryptography.CipherMode.CBC;
Padding = System.Security.Cryptography.PaddingMode.PKCS7
In Delphi i can't see any option to change PaddingMode and i guess it padds with zeros. If it is correct, then you should switch padding in C# to
System.Security.Cryptography.PaddingMode.Zeros
(sorry, can't check it, it is just assumption).
Update: As shunty mention, it works, just add line:
algorithm.Padding = PaddingMode.Zeros;
                        If you want to use the facility by the Spring framework in Delphi my suggestion is to create a Win32 [Library] DLL using Delphi and consume that DLL inside your .NET application. That sounds like a more logical solution than rewriting the code in C#(reinventing the wheel?).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With