Передать const unsigned char* в библиотеку DLL C#
сначала я хотел бы упомянуть, что я новичок в c++.
я работаю на C++ ядро системы на стороне сервера приложений(неуправляемые), на C# проверка подлинности системы, серверных приложений и C# клиентское приложение. я использую простые 2 функции для шифрования/дешифрования пакетов между сервером и клиентом шифрование и дешифрование идеально работает между 2 приложениями c# (клиент и сервер auth system)
Что я уже пробовал:
я попытался использовать тот же системный класс/функции в C++ core server, используя его следующим образом
using System::IO; using System::Security::Cryptography;
но не удалось завершить полный код в приложении C++.
так что это заставило меня задуматься о том, как насчет того, чтобы творить .dll в C# содержит эти две функции для шифрования/дешифрования данных в c++ ?
а вот C# .dll код криптографии
using System.Security.Cryptography; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System; namespace __Security { [Guid("413A1D2D-B7A8-42D7-8751-EB5D87F98873")] [ClassInterface(ClassInterfaceType.None)] [ProgId("__Security.Cryptography")] public class Cryptography : ICryptography { string CryptographyKey = "TESTINGKEY"; public char[] Decrypt(char[] IN) { char[] OUT; OUT = null; try { byte[] CLEAR_IN = IN.Select(c => (byte)c).ToArray(); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(CryptographyKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(CLEAR_IN, 0, CLEAR_IN.Length); cs.Close(); } OUT = System.Text.Encoding.Unicode.GetChars(ms.ToArray()); } } } catch(System.Exception E) { Debugger.Debug(E.Message); Debugger.Debug(E.StackTrace); }; return OUT; } } }
Икриптография
using System; using System.Runtime.InteropServices; namespace __Security { [Guid("B057AB41-D218-44AC-BEE6-66D41AC1AD90")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface ICryptography { [DispId(1)] char[] Encrypt(char[] IN); char[] Decrypt(char[] IN); }; }
а в приложении c++ я сделал что-то вроде этого:
#include <list> #import "__Security.tlb" raw_interfaces_only using namespace __Security; unsigned char* Kernel::Decrypt(unsigned char* _IN, int Len) { HRESULT hr = CoInitialize(NULL); ICryptographyPtr _Cryptography(__uuidof(Cryptography)); SAFEARRAY* SAFEARRAY_IN = GetSafeArray(_IN, 0); SAFEARRAY* *SAFEARRAY_OUT;//this is for return value HRESULT hr3 = _Cryptography->Decrypt(SAFEARRAY_IN, SAFEARRAY_OUT); if (!SUCCEEDED(hr3))// always fails { _com_error err(hr3); LPCTSTR errMsg = err.ErrorMessage(); _tprintf(errMsg); } CoUninitialize(); unsigned char* _OUT = new unsigned char[Len]; return _OUT; } SAFEARRAY* Kernel::GetSafeArray(const unsigned char* source, int codePage) { int Size = sizeof(source); CComSafeArray<BSTR> result(1); BSTR bstr = (BSTR)source; BSTR bstr2 = SysAllocString(bstr); HRESULT hr = result.SetAt(0, bstr2, FALSE); if (FAILED(hr)) AtlThrow(hr); return result.Detach(); }
Поэтому, когда я попытался отладить C# .dll, я получил сообщение об исключении с
SafeArrayTypeMismatchException
Теперь мне нужно знать, как безопасно отправить const unsigned char* в библиотеку dll C# и получить его обратно после выполнения шифрования/дешифрования.
если это неправильный путь, то я иду дальше... Итак, как мне преобразовать мой класс/функции криптографии C# в c++, чтобы быть совместимым со всеми 3 системными приложениями.