Ali Al-Masry Ответов: 1

Передать 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 системными приложениями.

1 Ответов

Рейтинг:
1

Alex Schunk

Почему вы используете массивы символов? COM способен использовать строки.