Обертка над libipriv.dll - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Помогите пожалуйста. Использую библиотеку libipriv.dll для расшифровки/шифровки данных. И тут понадобилось сгенерировать новый ключ. До меня работал человек, и была какая то программа для генерации карточек. Но человека нет, проги нет. В общем все печально. Нашел, все таки я что то похожее, и попытался сгенерировать. Код привожу ниже. И выдает вот такую ошибку.

Помощник по отладке управляемого кода "PInvokeStackImbalance" : "Вызов функции PInvoke "WindowsFormsApp2!WindowsFormsApp2.IPriv::Crypt_GenKeyCard" разбалансировал стек. Вероятно, это вызвано тем, что управляемая сигнатура PInvoke не совпадает с неуправляемой целевой сигнатурой. Убедитесь, что соглашение о вызовах и параметры сигнатуры PInvoke совпадают с неуправляемой целевой сигнатурой."

Вот экспорт библиотеки
 public class IPriv
    {
        // for internal usage only
        #region dll functions
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_Initialize();
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_Done();
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_OpenSecretKeyFromFile(
            int eng,
            [MarshalAs(UnmanagedType.LPStr)]string path,
            [MarshalAs(UnmanagedType.LPStr)]string passwd,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_OpenPublicKeyFromFile(
            int eng,
            [MarshalAs(UnmanagedType.LPStr)]string path,
            uint keyserial,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey,
            [MarshalAs(UnmanagedType.LPArray)]byte[] сakey);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_Sign(
            [MarshalAs(UnmanagedType.LPStr)]string src,
            int nsrc,
            [MarshalAs(UnmanagedType.LPStr)]StringBuilder dst,
            int ndst,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_Verify(
            [MarshalAs(UnmanagedType.LPStr)]string src,
            int nsrc,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pdst,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pndst,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_CloseKey(
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_GenKeyCard(
            [MarshalAs(UnmanagedType.LPStr)]StringBuilder dst,
            int ndst,
            [MarshalAs(UnmanagedType.LPStr)]string userid,
            long keyserial);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_GenKeyCardToFile(
            [MarshalAs(UnmanagedType.LPStr)]string path,
            [MarshalAs(UnmanagedType.LPStr)]string userid,
            long keyserial);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_GenKey(
            int eng,
            [MarshalAs(UnmanagedType.LPStr)]string src,
            int nsrc,
            [MarshalAs(UnmanagedType.LPArray)]byte[] skey,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey,
            int bits);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_GenKeyFromFile(
            int eng,
            [MarshalAs(UnmanagedType.LPStr)]string keycardpath,
            [MarshalAs(UnmanagedType.LPArray)]byte[] skey,
            [MarshalAs(UnmanagedType.LPArray)]byte[] pkey,
            int bits);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_ExportPublicKey(
            [MarshalAs(UnmanagedType.LPStr)]StringBuilder dst,
            int ndst,
            [MarshalAs(UnmanagedType.LPArray)]byte[] key,
            [MarshalAs(UnmanagedType.LPArray)]byte[] cakey);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_ExportPublicKeyToFile(
            [MarshalAs(UnmanagedType.LPStr)]string path,
            [MarshalAs(UnmanagedType.LPArray)]byte[] key,
            [MarshalAs(UnmanagedType.LPArray)]byte[] cakey);
 
        // Экспорт закрытого ключа (может не поддерживаться криптопровайдером).
        // dst: выходной, буфер для приема закрытого ключа
        // ndst: входной, максимальная длина приемного буфера
        // path: входной, путь к файлу для закрытого ключа
        // passwd: входной, кодовая фраза для шифрования закрытого ключа
        // key: входной, закрытый ключ
        // Возвращает: длина тела ключа или код ошибки
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_ExportSecretKey(
            [MarshalAs(UnmanagedType.LPStr)]StringBuilder dst,
            int ndst,
            [MarshalAs(UnmanagedType.LPStr)]string passwd,
            [MarshalAs(UnmanagedType.LPArray)]byte[] key);
 
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_ExportSecretKeyToFile(
            [MarshalAs(UnmanagedType.LPStr)]string path,
            [MarshalAs(UnmanagedType.LPStr)]string passwd,
            [MarshalAs(UnmanagedType.LPArray)]byte[] key);
 
        #endregion

        /// <summary>
        /// Инициализирует криптосистему. Запускать один раз за все приложение.
        /// </summary>
        public static void Initialize()
        {
            Crypt_Initialize();
        }
 
        /// <summary>
        /// Закрывает криптосистему. Запускать один раз за все приложение.
        /// </summary>
        public static void Done()
        {
            Crypt_Done();
        }
 
        /// <summary>
        /// Загружает секретный ключ
        /// </summary>
        /// <param name="path">Путь к файлу ключа</param>
        /// <param name="passwd">Пароль к ключу</param>
        /// <returns></returns>
        public static IPrivKey openSecretKey(string path, string passwd)
        {
            IPrivKey k = new IPrivKey();
            int rc = Crypt_OpenSecretKeyFromFile(0, path, passwd, k.getKey());
            if (rc != 0)
                throw (new IPrivException(rc));
            return k;
        }
 
        /// <summary>
        /// Загружает открытый ключ
        /// </summary>
        /// <param name="path">Файл ключа</param>
        /// <param name="keyserial">Серийный ключ</param>
        /// <returns></returns>
        public static IPrivKey openPublicKey(string path, uint keyserial)
        {
            IPrivKey k = new IPrivKey();
            int rc = Crypt_OpenPublicKeyFromFile(0, path, keyserial, k.getKey(), null);
            if (rc != 0)
                throw (new IPrivException(rc));
            return k;
        }
 
        /// <summary>
        /// Подписывает сообщение секретным ключом
        /// </summary>
        /// <param name="src">Сообщение</param>
        /// <param name="key">Секретный ключ</param>
        /// <returns></returns>
        public static string signText(string src, IPrivKey key)
        {
            string dst;
            StringBuilder tmp = new StringBuilder(Encoding.UTF8.GetByteCount(src) + 1024);
            int rc = Crypt_Sign(src, src.Length, tmp, tmp.Capacity, key.getKey());
            if (rc < 0)
                throw (new IPrivException(rc));
            dst = tmp.ToString(0, rc);
            return dst;
        }
 
        /// <summary>
        /// Проверяет сообщение открытым ключом
        /// </summary>
        /// <param name="src">Сообщение</param>
        /// <param name="key">Открытый ключ</param>
        /// <returns></returns>
        public static string verifyText(string src, IPrivKey key)
        {
            int rc = Crypt_Verify(src, -1, null, null, key.getKey());
            if (rc != 0)
                throw (new IPrivException(rc));
            return "";
        }
 
        /// <summary>
        /// Закрывает ключ
        /// </summary>
        /// <param name="key"></param>
        public static void closeKey(IPrivKey key)
        {
            Crypt_CloseKey(key.getKey());
        }
 
        /// <summary>
        /// Генерирует карточку ключа на основе идентификатора пользователя и его ключа
        /// </summary>
        /// <param name="userId">Идентификатор пользователя, для которого генерируется карточка</param>
        /// <param name="serialKey">Серийный ключ карточки</param>
        /// <returns></returns>
        public static string GenerateCard(string userId, int serialKey)
        {
            string card = "";
            StringBuilder tmp = new StringBuilder(10048);
            int rc = Crypt_GenKeyCard(tmp, tmp.Capacity, userId, (long)serialKey);
            if (rc < 0)
                throw (new IPrivException(rc));
            card = tmp.ToString(0, rc);
            return card;
        }
 
        /// <summary>
        /// Генерирует карточку в файл
        /// </summary>
        /// <param name="filename">Имя файла</param>
        /// <param name="userId">Id пользователя</param>
        /// <param name="serialKey">Серийный ключ</param>
        public static void GenerateCardToFile(string filename, string userId, int serialKey)
        {
            int rc = Crypt_GenKeyCardToFile(filename, userId, (long)serialKey);
            if (rc < 0)
                throw (new IPrivException(rc));
        }
 
        /// <summary>
        /// Генерирует ключи на основе раннее сгенерированной карточки
        /// </summary>
        /// <param name="card">Карточка ключа</param>
        /// <param name="skey">Секретный ключ</param>
        /// <param name="pkey">Открытый ключ</param>
        public static void GenerateKey(string card, IPrivKey skey, IPrivKey pkey)
        {
            IPrivKey SKey = new IPrivKey();
            IPrivKey PKey = new IPrivKey();
 
            Crypt_GenKey(0, card, -1, SKey.getKey(), PKey.getKey(), 512);
 
            skey = SKey;
            pkey = PKey;
        }
 
        /// <summary>
        /// Экспорт закрытого ключа
        /// </summary>
        /// <param name="skey">Ключ</param>
        /// <param name="passwd">Пароль</param>
        /// <returns></returns>
        public static string ExportSecretKey(IPrivKey skey, string passwd)
        {
            StringBuilder sb = new StringBuilder(10048);
            Crypt_ExportSecretKey(sb, sb.Capacity, passwd, skey.getKey());
 
            return sb.ToString();
        }
 
        /// <summary>
        /// Экспорт закрытого ключа в файл
        /// </summary>
        /// <param name="filename">Имя файла</param>
        /// <param name="key">Ключ</param>
        /// <param name="passwd">Пароль</param>
        public static void ExportSecretKeyToFile(string filename, IPrivKey key, string passwd)
        {
            Crypt_ExportSecretKeyToFile(filename, passwd, key.getKey());
        }
 
        /// <summary>
        /// Экспорт открытого ключа
        /// </summary>
        /// <param name="pkey">Ключ</param>
        /// <param name="skey">Серийный ключ</param>
        /// <returns></returns>
        public static string ExportPublicKey(IPrivKey pkey, IPrivKey skey)
        {
            StringBuilder sb = new StringBuilder(10048);
            Crypt_ExportPublicKey(sb, sb.Capacity, pkey.getKey(), skey.getKey());
            return sb.ToString();
        }
    };
А вот сам код
 private void button1_Click(object sender, EventArgs e)
        {
                IPriv.Initialize();
                string val = "";
 
                try
                {
                    val = IPriv.GenerateCard(textBox1.Text, Convert.ToInt32(numericUpDown1.Value));
                    IPriv.GenerateCardToFile(textBox1.Text + ".dat", textBox1.Text, Convert.ToInt32(numericUpDown1.Value));
 
                    IPrivKey skey = new IPrivKey();
                    IPrivKey pkey = new IPrivKey();

                    IPriv.GenerateKey(val, skey, pkey);
 
                    pkey.closeKey();
                    skey.closeKey();
 
                }
                catch (IPrivException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
 
               IPriv.Done();
        }
Что интересно функции шифрования, таких проблем в этом же проекте не вызывают. Манифест о вызове неуправляемого кода, пытался добавлять
CallingConvention = CallingConvention.StdCall
. Ошибка та же. Помогите будьте добры. Не силен в использовании нативных библиотек.

Решение задачи: «Обертка над libipriv.dll»

textual
Листинг программы
        [DllImport("libipriv.dll")]
        internal static extern int Crypt_GenKeyCard(
            [MarshalAs(UnmanagedType.LPStr)]StringBuilder dst,
            int ndst,
            [MarshalAs(UnmanagedType.LPStr)]string userid,
            uint keyserial);

Оцени полезность:

14   голосов , оценка 3.929 из 5