//-------------------------------------------------------------------- // Пример создания ключевого контейнера с именем, передаваемым в качестве // параметра командной строки. Если параметр не указан, то будет создан // контейнер с именем по умолчанию. В контейнере созданиются два ключа // (ключ обмена и ключ подписи). //-------------------------------------------------------------------- static HCRYPTPROV hCryptProv = 0; // Дескриптор контекста критографического провайдера. static HCRYPTKEY hKey = 0; // Дескриптор открытого/закрытого ключа. static void CleanUp(void); static void HandleError(char *s); int main(int argc, char *argv[]) { // Объявление и инициализация переменных. LPSTR pszUserName; // Буфер для хранения имени ключевого контейнера. DWORD dwUserNameLen; // Длина буфера. LPCSTR UserName; // Добавленное по выбору имя пользователя // здесь будет использовано как имя // ключевого контейнера (ограничение на 100 символов). // Начало выполнения. Получение имени создаваемого контейнера. if(argc < 2) HandleError(" using: CreatingKeyContainer.exe <container_name>"); UserName = argv[1]; // Для создания нового ключевого контейнера строка второго параметра // заменяется на NULL здесь и при следующем вызове функции: if(CryptAcquireContextA( &hCryptProv, // Дескриптор CSP UserName, // Имя контейнера NULL, // Использование провайдера по умолчанию PROV_GOST_2012_256, // Тип провайдера 0)) // Значения флагов { printf("A cryptcontext with the %s key container has been acquired.\n", UserName); } else { // Создание нового контейнера. if(!CryptAcquireContextA( &hCryptProv, UserName, NULL, PROV_GOST_2012_256, CRYPT_NEWKEYSET)) { HandleError("Could not create a new key container.\n"); } printf("A new key container has been created.\n"); } // Криптографический контекст с ключевым контейнером доступен. Получение // имени ключевого контейнера. if(!CryptGetProvParam( hCryptProv, // Дескриптор CSP PP_CONTAINER, // Получение имени ключевого контейнера NULL, // Указатель на имя ключевого контейнера &dwUserNameLen, // Длина имени 0)) { // Ошибка получении имени ключевого контейнера HandleError("error occurred getting the key container name."); } // Лучше использовать auto_ptr: //std::auto_ptr<char> aptrUserName(new char[dwUserNameLen+1]); //szUserName = aptrUserName.get(); pszUserName=(char *)malloc((dwUserNameLen+1)); if(!CryptGetProvParam( hCryptProv, // Дескриптор CSP PP_CONTAINER, // Получение имени ключевого контейнера (LPBYTE)pszUserName, // Указатель на имя ключевого контейнера &dwUserNameLen, // Длина имени 0)) { // Ошибка получении имени ключевого контейнера free(pszUserName); HandleError("error occurred getting the key container name."); } else { printf("A crypto context has been acquired and \n"); printf("The name on the key container is %s\n\n", pszUserName); free(pszUserName); } // Контекст с ключевым контейнером доступен, // попытка получения дескриптора ключа подписи if(CryptGetUserKey( hCryptProv, // Дескриптор CSP AT_SIGNATURE, // Спецификация ключа &hKey)) // Дескриптор ключа { printf("A signature key is available.\n"); } else { printf("No signature key is available.\n"); // Ошибка в том, что контейнер не содержит ключа. if(!(GetLastError() == (DWORD)NTE_NO_KEY)) HandleError("An error other than NTE_NO_KEY getting signature key.\n"); // Создание подписанной ключевой пары. printf("The signature key does not exist.\n"); printf("Creating a signature key pair...\n"); if(!CryptGenKey( hCryptProv, AT_SIGNATURE, 0, &hKey)) { HandleError("Error occurred creating a signature key.\n"); } printf("Created a signature key pair.\n"); } // Получение ключа обмена: AT_KEYEXCHANGE if(CryptGetUserKey( hCryptProv, AT_KEYEXCHANGE, &hKey)) { printf("An exchange key exists. \n"); } else { printf("No exchange key is available.\n"); } CleanUp(); printf("Everything is okay. A signature key\n"); printf("pair and an exchange key exist in\n"); printf("the %s key container.\n", UserName); return 0; } // Конец примера
AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Ядро Windows NT: не поддерживает.