#2 Re: mORMot 1 » SynCrypto Example: Encrypt in Delphi Decrypt in C# » 2020-06-30 13:08:55

Then how do I get the IV back in C#?
Are those the first 16 bytes there as well?

#3 Re: mORMot 1 » SynCrypto Example: Encrypt in Delphi Decrypt in C# » 2020-06-30 12:53:54

I customized it so that the IV is now randomly generated and appended before the Base64 encoding

  CopyMemory(@Key, @AKey[1], 32);
  CreateGUID(IVGUID);
  InBytes := TEncoding.Unicode.GetBytes(ASource);
  IvBytes := IVGUID.ToByteArray;

  Move(IvBytes[0], IV, 16);

.....

  Result := TNetEncoding.Base64.EncodeBytesToString(Concat(IvBytes, OutBytes));

In C# I do the same thing when compiling the streams:

                byte[] key = Encoding.ASCII.GetBytes(Key).Take(32).ToArray();
                byte[] vec = Convert.FromBase64String(input).Take(16).ToArray();
.....
                byte[] InfutData = Convert.FromBase64String(input).Skip(16).ToArray();
                inputStream = new MemoryStream(InfutData);

Thanks for clarifying, hope this is so common practice and safe?

#4 Re: mORMot 1 » SynCrypto Example: Encrypt in Delphi Decrypt in C# » 2020-06-30 09:28:38

ok, I will in the future. I have read up a little on the topic initialization vector.

Would it be ok if I used a hash over the data itself as IV?

#5 Re: mORMot 1 » SynCrypto Example: Encrypt in Delphi Decrypt in C# » 2020-06-30 08:30:25

I have a solution and wanted to share it with you, maybe someone can tell me if I did everything right yikes)

Delphi Code

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, SynCripto, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    GridPanel1: TGridPanel;
    mmoInput: TMemo;
    mmoOutput: TMemo;
    btnEncrypt: TButton;
    btnDecrypt: TButton;
    procedure btnEncryptClick(Sender: TObject);
    procedure btnDecryptClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  KeyStr: AnsiString;
  Key: TSHA256Digest;
  IVStr: AnsiString;
  IV: TAESBlock;

  Form1: TForm1;

implementation

uses
  System.NetEncoding,
  System.IOUtils;

{$R *.dfm}

procedure TForm1.btnEncryptClick(Sender: TObject);
var
  AES: TAESCBC;
  InBytes, OutBytes: TBytes;
begin
  KeyStr := '6078C40F64D3516E9294D9C3D4D45D80';
  IVStr := '9978B3B4893D00EC';
  CopyMemory(@Key, @KeyStr[1], 32);
  CopyMemory(@IV, @IVStr[1], 16);


  InBytes := TEncoding.Unicode.GetBytes(mmoInput.Lines.Text);

  AES := TAESCBC.Create(Key, 256);
  try
    AES.IV := IV;
    OutBytes := AES.EncryptPKCS7(InBytes, False);
  finally
    FreeAndNil(AES);
  end;

  mmoOutput.Lines.Text := TNetEncoding.Base64.EncodeBytesToString(OutBytes);
end;

procedure TForm1.btnDecryptClick(Sender: TObject);
var
  AES: TAESCBC;
  InBytes, OutBytes: TBytes;
begin
  KeyStr := '6078C40F64D3516E9294D9C3D4D45D80';
  IVStr := '9978B3B4893D00EC';
  CopyMemory(@Key, @KeyStr[1], 32);
  CopyMemory(@IV, @IVStr[1], 16);

  InBytes := TNetEncoding.Base64.DecodeStringToBytes(mmoOutput.Lines.Text);

  AES := TAESCBC.Create(Key, 256);
  try
    AES.IV := IV;
    OutBytes := AES.DecryptPKCS7(InBytes, False);
  finally
    FreeAndNil(AES);
  end;

  mmoInput.Lines.Text := TEncoding.Unicode.GetString(OutBytes);
end;

end.

C# Code to Decrypt:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace AES_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string soutput = "";
            AESDecryptBase64String("ZdBFopJw0o80ESiSUyKG2aaxyK6AU40yYzzmPZ2tmYHN6WWQUQgrYxw3BI7LWtPk5Lc06qvnshSGibiVZ2ig7w==", out soutput);
            Console.WriteLine(soutput);
            Console.ReadLine();
        }
        public static Stream GenerateStreamFromString(string s)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(s);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }
        static public void AESDecryptBase64String(string input, out string output)
        {
            MemoryStream inputStream = null;
            Stream outputStream = null;
            CryptoStream cryptoStream = null;
            output = "";

            try
            {
                byte[] key = Encoding.ASCII.GetBytes("6078C40F64D3516E9294D9C3D4D45D80");
                byte[] vec = Encoding.ASCII.GetBytes("9978B3B4893D00EC");

                outputStream = GenerateStreamFromString(output);

                AesManaged aesCrypto = new AesManaged();
                aesCrypto.BlockSize = 8 * 16;
                aesCrypto.KeySize = 8 * 32;
                aesCrypto.Padding = PaddingMode.PKCS7;
                aesCrypto.Mode = CipherMode.CBC;
                aesCrypto.IV = vec;

                cryptoStream = new CryptoStream(outputStream, aesCrypto.CreateDecryptor(key, vec), CryptoStreamMode.Write);
                inputStream = new MemoryStream(Convert.FromBase64String(input));

                int length;
                byte[] buffer = new byte[16];

                while ((length = inputStream.Read(buffer, 0, 16)) != 0)
                {
                    cryptoStream.Write(buffer, 0, length);
                }
                cryptoStream.FlushFinalBlock();
                outputStream.Position = 0;
                StreamReader reader = new StreamReader(outputStream, Encoding.Unicode);
                output = reader.ReadToEnd();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (cryptoStream != null)
                {
                    cryptoStream.Close();
                }

                if (outputStream != null)
                {
                    outputStream.Close();
                }

                if (inputStream != null)
                {
                    inputStream.Close();
                }
            }
        }

    }
}

the line cryptoStream.FlushFinalBlock(); is very important, because otherwise partly (I think depending on the length of the data) not everything was decrypted back.

#7 mORMot 1 » SynCrypto Example: Encrypt in Delphi Decrypt in C# » 2020-06-29 13:03:35

der.Christoph
Replies: 10

I am looking for a working example to encrypt strings (or streams) in Delphi and decrypt them in C#.

I'm new to crypto and would be happy if it works in C# without any additional components.
the example is about stability. It would be good if somebody can name a SynCrypto function and all related encryption parameters, bit length, cypher modes and everything else you need ....

And then the appropriate C# code yikes), can someone show me a good example?


thanks!

Board footer

Powered by FluxBB