typedef struct _PROV_ENUMALGS {

ALG_ID aiAlgid; // идентификатор алгоритма

DWORD dwBitLen; // длина ключа

DWORD dwNameLen; // длина имени алгоритма

CHAR szName[20]; // имя алгоритма

} PROV_ENUMALGS;

PP_ENUMALGS_EX: расширенная информация об алгоритме (вариант PP_ENUMALGS).

typedef struct _PROV_ENUMALGS_EX {

ALG_ID aiAlgid; // идентификатор алгоритма

DWORD dwDefaultLen; // длина ключа по умолчанию

DWORD dwMinLen; // минимальная длина ключа

DWORD dwMaxLen; // максимальная длина ключа

DWORD dwProtocols; // количество поддерживаемых протоколов

DWORD dwNameLen; // длина короткого имени протокола

CHAR szName[20]; // строка с именем поддерживаемого протокола

DWORD dwLongNameLen; // длина полного имени протокола

CHAR szLongName[40]; // строка с длинным именем протокола

} PROV_ENUMALGS_EX;

PP_ENUMCONTAINERS: строка с именем одного из контейнеров ключей поддерживаемого криптопровайдером. Список получается так же как и с помощью PP_ENUMALGS.

PP_IMPTYPE: значение DWORD, означающее вид реализации криптопровайдера. CRYPT_IMPL_HARDWARE – аппаратный, CRYPT_IMPL_SOFTWARE – программный, CRYPT_IMPL_MIXED аппаратно-программный, CRYPT_IMPL_UNKNOWN – неизвестный.

PP_NAME: строка с именем криптопровайдера.

PP_VERSION: номер версии криптопровайдера. Два младших байта содержат номер версии.

PP_SIG_KEYSIZE_INC и PP_KEYX_KEYSIZE_INC: шаг изменения длины ключей подписи и обмена.

PP_KEYSET_SEC_DESCR: указатель на дескриптор безопасности контейнера ключей.

PP_PROVTYPE: значение DWORD, соответствующее типу криптопровайдера.

НЕ нашли? Не то? Что вы ищете?

PP_USE_HARDWARE_RNG: проверяет поддержку аппаратного генератора случайных чисел. Если поддерживается, то функция возвращает TRUE, если нет – FALSE. При использовании этого значения параметр pbData должен быть равен NULL, а dwFlags – 0.

PP_KEYSPEC: возвращает информацию о поддерживаемых криптопровайдером спецификаторах ключа.

Некоторые возможные значения dwFlags:

CRYPT_FIRST используется при получении списка для выдачи первого значения.

CRYPT_MACHINE_KEYSET может использоваться совместно с PP_ENUMCONTAINERS для получения списка системных (а не пользовательских) контейнеров ключей.

Возвращаемые значения: если все прошло нормально, ненулевое (TRUE), если произошла ошибка, то возвращается нуль (FALSE). Для анализа ошибки нужно вызвать GetLastError. Если она вернула значение ERROR_NO_MORE_ITEMS, то это не ошибка, а сигнал окончания списка. Если она вернула ERROR_MORE_DATA, то буфер pbData недостаточен для размещения в нем информации. Если она вернула ERROR_INVALID_PARAMETER, ERROR_INVALID_HANDLE, NTE_BAD_FLAGS или NTE_BAD_UID, значит один из параметров является неправильным. Таблица кодов остальных ошибок находится в MSDN.

CryptReleaseContext

освобождает дескриптор криптопровайдера и контейнера ключей. При каждом вызове этой функции счетчик подключений уменьшается на единицу. Когда он достигает нуля, контекст полностью освобождается и не может использоваться никакой функцией приложения. Приложение вызывает эту функцию после окончания использования криптопровайдера. После ее вызова дескриптор провайдера более недействителен. Функция не уничтожает контейнеры ключей или ключевые пары.

BOOL WINAPI CryptReleaseContext(

HCRYPTPROV hProv, //[вх] дескриптор криптопровайдера, созданный вызовом CryptAcquireContext.

DWORD dwFlags //[вх] должен быть 0. Оставлен для использования в будущем.

);

Возвращаемые значения: если все прошло нормально, ненулевое (TRUE), если произошла ошибка, то возвращается нуль (FALSE). Для анализа ошибки нужно вызвать GetLastError. Если она вернула ERROR_BUSY, то контекст криптопровайдера в данный момент используется другим процессом. Если она вернула ERROR_INVALID_PARAMETER, ERROR_INVALID_HANDLE, NTE_BAD_FLAGS или NTE_BAD_UID, значит один из параметров является неправильным. Таблица кодов остальных ошибок находится в MSDN.

Примечания. После вызова функции сеанс работы криптопровайдера заканчивается и все существующие сеансовые ключи и хеш-объекты созданные с использованием дескриптора hProv становятся недействительными. В практике все эти объекты должны быть уничтожены вызовами CryptDestroyKey и CryptDestroyHash до вызова CryptReleaseContext.

Пример программы, использующей основные функции

#include "stdafx. h"

#define _WIN32_WINNT 0x0500

#define WINVER 0x0500

#include <stdio. h>

#include <windows. h>

#include <wincrypt. h>

void HandleError(char *s)

{

printf("An error occurred in running the program.\n");

printf("%s\n",s);

printf("Error number %x\n.",GetLastError());

printf("Program terminating.\n");

exit(1);

}

void main()

{

HCRYPTPROV hProv; // Дескриптор криптопровайдера

LPTSTR pszName;

DWORD dwType;

DWORD cbName;

DWORD dwIndex=0;

BYTE *ptr;

ALG_ID aiAlgid;

DWORD dwBits;

DWORD dwNameLen;

CHAR szName[100]; // Часто выделяется динамически

BYTE pbData[1024];// Часто выделяется динамически

DWORD cbData=1024;

DWORD dwIncrement = sizeof(DWORD);

DWORD dwFlags=CRYPT_FIRST;

DWORD dwParam = PP_CLIENT_HWND;

CHAR *pszAlgType = NULL;

BOOL fMore=TRUE;

LPTSTR pbProvName;

DWORD cbProvName;

//--------------------------------------------------------------

// Печать заголовка таблицы типов криптопровайдеров.

printf("\n Listing Available Provider Types.\n");

printf("Type Provider Type Name\n");

printf("____ ________________________________\n");

// Цикл перечисления типов криптопровайдеров.

dwIndex = 0;

while(CryptEnumProviderTypes(

dwIndex, // вх -- dwIndex

NULL, // вх -- pdwReserved - установить NULL

0, // вх -- dwFlags – установить 0

&dwType, // вых -- pdwProvType

NULL, // вых -- pszProvName -- NULL при первом вызове

&cbName // вх, вых -- pcbProvName

))

{

//--------------------------------------------------------------------

// cbName — длина имени следующего типа криптопровайдеров.

// Выделяем участок памяти для размещения этого имени.

if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))

{

HandleError("ERROR - LocalAlloc failed!");

}

//--------------------------------------------------------------------

// Получаем название типа криптопровайдера.

if (CryptEnumProviderTypes(

dwIndex++,

NULL,

NULL,

&dwType,

pszName,

&cbName))

{

printf ("%4.0d %s\n",dwType, pszName);

}

else

{

HandleError("ERROR - CryptEnumProviders");

}

LocalFree(pszName);

}

//--------------------------------------------------------------

// Печать заголовка списка криптопровайдеров.

printf("\n\n Listing Available Providers.\n");

printf("Type Provider Name\n");

printf("____ ________________________________\n");

//----------------------------------------------------------------

// Цикл перечисления криптопровайдеров.

dwIndex = 0;

while(CryptEnumProviders(

dwIndex, // in -- dwIndex

NULL, // in -- pdwReserved - установить NULL

0, // in -- dwFlags – установить 0

&dwType, // out -- pdwProvType

NULL, // out -- pszProvName -- NULL при первом вызове

&cbName // in, out -- pcbProvName

))

{

//--------------------------------------------------------------------

// cbName — длина имени следующего криптопровайдера.

// Выделяем участок памяти для размещения этого имени.

if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))

{

HandleError("ERROR - LocalAlloc failed!");

}

//--------------------------------------------------------------------

// Получаем название криптопровайдера.

if (CryptEnumProviders(

dwIndex++,

NULL,

0,

&dwType,

pszName,

&cbName // pcbProvName – размер pszName

))

{

printf ("%4.0d %s\n",dwType, pszName);

}

else

{

HandleError("ERROR - CryptEnumProviders");

}

LocalFree(pszName);

} // Конец цикла while

//-----------------------------------------------------------------

// Получаем имя провайдера по умолчанию относящегося к PROV_RSA_FULL

//

//---------------------------------------------------------------

// Получаем длину его имени.

if (!(CryptGetDefaultProvider(

PROV_RSA_FULL,

NULL,

CRYPT_MACHINE_DEFAULT,

NULL,

&cbProvName)))

{

HandleError("Error getting the length of the default provider name.");

}

//---------------------------------------------------------------

// Выделяем память для размещения имени криптопровайдера по умолчанию

if (!(pbProvName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbProvName)))

{

HandleError("Error during memory allocation for provider name.");

}

//---------------------------------------------------------------

// Получаем имя криптопровайдера типа PROV_RSA_FULL.

if (CryptGetDefaultProvider(

PROV_RSA_FULL,

NULL,

CRYPT_MACHINE_DEFAULT,

pbProvName,

&cbProvName))

{

printf("\n\nThe default provider name is %s\n\n",pbProvName);

}

else

{

HandleError("Getting the name of the provider failed.");

}

//-----------------------------------------------------

// Получаем криптографический контекст (инициализируем криптопровайдер).

if(!CryptAcquireContext(

&hProv,

NULL,

NULL,

PROV_RSA_FULL,

CRYPT_VERIFYCONTEXT

))

{

HandleError("Error during CryptAcquireContext!");

}

//------------------------------------------------------

// Получаем список поддерживаемых алгоритмов.

//------------------------------------------------------

// Печать заголовка таблицы информации об алгоритмах

printf(" Enumerating the supported algorithms\n\n");

printf(" Algid Bits Type Name Algorithm\n");

printf(" Length Name\n");

printf(" ________________________________________________________\n");

while(fMore)

{

//------------------------------------------------------

// Получение информации об очередном алгоритме.

if(CryptGetProvParam(hProv, PP_ENUMALGS, pbData, &cbData, dwFlags))

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4