Я не могу вызвать шифрование Lockbox 3 AES, написанное на Delphi, из C#

#c# #delphi

#c# #delphi

Вопрос:

Я написал функцию для шифрования строки в Delphi 10. Все работает нормально, у меня есть такая же функция в Winform, и результат отображается в поле Memo, однако, когда я вызываю функцию из C #, я получаю сообщение об ошибке, когда я запускаю эту функцию шифрования вызова из C #, я получаю «Параметр не найден», который является результатом исключения в Delphi.

Кто-нибудь может здесь помочь?

 function Encrypt(str: PWideChar; len: Integer): Boolean; stdcall;
 begin
  try
   eString := AES128_Encrypt('Test','TestPassword');
   PwValue := PWideChar(eString);
    StrLCopy(str, PwValue, len);
    Result := true;
  except
    On E: Exception do
    begin
    PwValue := PWideChar(E.Message);
    StrLCopy(str, PwValue, len);
    end;
  end;

end;

function AES128_Encrypt(Value, Password: string): string; stdcall;
var
  hCProv: HCRYPTPROV;
  hKey: HCRYPTKEY;
  lul_datalen: Integer;
  lul_buflen: Integer;
  Buffer: TBytes;
begin
  Assert(Password <> '');
  if (Value = '') then
    Result := ''
  else begin
    hCProv := __CryptAcquireContext(PROV_RSA_AES);
    try
      hKey := __AES128_DeriveKeyFromPassword(hCProv, Password);
      try
        // allocate buffer space
        lul_datalen := Length(Value) * SizeOf(Char);
        Buffer := TEncoding.Unicode.GetBytes(Value   '        ');
        lul_buflen := Length(Buffer);
        // encrypt to buffer
        Win32Check(CryptEncrypt(hKey, 0, True, 0, @Buffer[0], lul_datalen, lul_buflen));
        SetLength(Buffer, lul_datalen);
        // base 64 result
        Result := Base64_Encode(Buffer);
      finally
        CryptDestroyKey(hKey);
      end;
    finally
      CryptReleaseContext(hCProv, 0);
    end;
  end;
end;
  

Вызывая его как

 eString := AES128_Encrypt('ii', 'o3ew232we22o');
  

Код на C #

  [DllImport(@"<Path of dll>", EntryPoint = "Enrypt", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern bool Enrypt(StringBuilder sb, int len);

public static string Encrypt()
{
    try
    {
      StringBuilder str = new StringBuilder(256);
 System.Threading.Thread.CurrentThread.SetApartmentState(System.Threading.ApartmentState.STA);
      bool result =  Encrypt(str, str.Capacity);
    
      if (result)
      {
          return str.ToString();
       }
    }            
 catch (Exception ex1)
 {
    MessageBox.Show(ex1.ToString());
 }
    
 return "";
 }
  

Комментарии:

1. где находится код c #?

2. опубликовал полный код

3. 2 замечания, 1) отметьте вашу процедуру шифрования delphi как stdcall, если вы не укажете соглашение о вызове, по умолчанию это будет cdecl. 2) Используйте Widestring на стороне delphi и маршалируйте как BSTR на C #. Pwidechar и stringbuilder несовместимы

4. Я пометил функцию как stdcall (пожалуйста, смотрите Обновленный код). Я не получаю второй комментарий. Если я заменю свой AES128_Encrypt (‘Test’, ‘TestPassword’) на ‘некоторый мусор, который я хотел вернуть’, он просто отлично работает

5. Pwidechar Delphi не может быть маршалирован как конструктор строк c #, это так просто.