Обертка над 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);