//-------------------------------------------------------------------- // Пример создания ключевого контейнера с именем, передаваемым в качестве // параметра командной строки. Если параметр не указан, то будет создан // контейнер с именем по умолчанию. В контейнере созданиются два ключа // (ключ обмена и ключ подписи). //-------------------------------------------------------------------- static HCRYPTPROV hCryptProv = 0; // Дескриптор контекста критографического провайдера. static HCRYPTKEY hKey = 0; // Дескриптор открытого/закрытого ключа. static void CleanUp(void); static void HandleError(const 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."); } 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: 6/7.
FreeBSD: 11/12, pfSense 2.x.
Linux: LSB 4.x (RHEL 5/6/7/8, SuSE 11SP4/12/15, Oracle Linux 5/6/7/8, CentOS 6/7/8, Ubuntu 14.04/16.04/18.04/19.10, Linux Mint 18/19, Fedora 28/29/30/31, Debian 8/9/10 и др.).
Solaris: 10/11.
Mac OS X: 10.9/10.10/10.11/10.12/10.13/10.14/10.15.
iOS: 8/9/10/11/12/13.
Sailfish: 2/3.
Windows: 7/8/8.1/10, Server 2008/2008R2/2012/2012R2/2016/2019.