Функция CryptAcquireContextA (wincrypt.h)
Эта функция сначала пытается найти CSP с характеристиками, описанными в параметрах dwProvType и szProvider . Если поставщик служб конфигурации найден, функция пытается найти в CSP контейнер ключей, соответствующий имени, заданному параметром szContainer . Чтобы получить контекст и контейнер ключей закрытого ключа , связанного с открытым ключом сертификата, используйте CryptAcquireCertificatePrivateKey.
При наличии соответствующего параметра dwFlags эта функция также может создавать и уничтожать контейнеры ключей, а также предоставлять доступ к CSP с помощью контейнера временных ключей, если доступ к закрытому ключу не требуется.
Синтаксис
BOOL CryptAcquireContextA(
[out] HCRYPTPROV *phProv,
[in] LPCSTR szContainer,
[in] LPCSTR szProvider,
[in] DWORD dwProvType,
[in] DWORD dwFlags
);
Параметры
[out] phProv
Указатель на дескриптор CSP. Завершив использование CSP, отпустите дескриптор, вызвав функцию CryptReleaseContext .
[in] szContainer
Имя контейнера ключа. Это строка, заканчивающаяся null, которая определяет контейнер ключей для CSP. Это имя не зависит от метода, используемого для хранения ключей. Некоторые поставщики служб конфигурации хранят контейнеры ключей внутри (на оборудовании), некоторые используют системный реестр, а другие — файловую систему. В большинстве случаев, когда dwFlags имеет значение CRYPT_VERIFYCONTEXT, szContainer должен иметь значение NULL. Однако для аппаратных CSP, таких как поставщик служб конфигурации смарт-карт, можно получить доступ к общедоступной информации в спецификации контейнера.
Дополнительные сведения об использовании параметра szContainer см. в разделе Примечания.
[in] szProvider
Строка, заканчивающаяся null, которая содержит имя используемого поставщика служб CSP.
Если этот параметр имеет значение NULL, используется поставщик по умолчанию для пользователя. Дополнительные сведения см. в разделе Контексты поставщика служб шифрования. Список доступных поставщиков шифрования см. в разделе Имена поставщиков шифрования.
Приложение может получить имя используемого CSP с помощью функции CryptGetProvParam для чтения значения PP_NAME CSP в параметре dwParam .
Поставщик служб CSP по умолчанию может изменяться между выпусками операционной системы. Чтобы обеспечить взаимодействие на разных платформах операционной системы, поставщик служб CSP должен быть явно задан с помощью этого параметра, а не CSP по умолчанию.
[in] dwProvType
Указывает тип поставщика для получения. Определенные типы поставщиков рассматриваются в разделе Типы поставщиков шифрования.
[in] dwFlags
Значения флага. Этот параметр обычно равен нулю, но некоторые приложения устанавливают один или несколько из следующих флагов.
Значение | Значение |
---|---|
|
Этот параметр предназначен для приложений, использующих временные ключи, или приложений, которым не требуется доступ к сохраненным закрытым ключам, например для приложений, выполняющих только хэширование, шифрование и проверку цифровой подписи . Доступ к закрытому ключу требуется только приложениям, которые создают подписи или расшифровывают сообщения. В большинстве случаев этот флаг должен быть установлен.
Для файловых поставщиков служб конфигурации при установке этого флага параметр szContainer должен иметь значение NULL. Приложение не имеет доступа к сохраненным закрытым ключам пар открытых и закрытых ключей. Если этот флаг установлен, можно создать временные пары открытого и закрытого ключей , но они не сохраняются. Для аппаратных CSP, таких как поставщик служб конфигурации смарт-карты, если параметр szContainer имеет значение NULL или пустой, этот флаг означает, что доступ к ключам не требуется и пользователь не должен представлять пользовательский интерфейс. Эта форма используется для подключения к CSP для запроса его возможностей, но не для фактического использования ключей. Если параметр szContainer не равен NULL и не является пустым, то этот флаг означает, что требуется доступ только к общедоступным сведениям в указанном контейнере. Поставщик служб CSP не должен запрашивать ПИН-код. Попытки получить доступ к личной информации (например, функции CryptSignHash ) завершатся ошибкой. При вызове CryptAcquireContext многие поставщики служб конфигурации требуют ввода данных от пользователя-владельце, прежде чем предоставлять доступ к закрытым ключам в контейнере ключей. Например, закрытые ключи можно зашифровать, требуя пароль от пользователя перед их использованием. Однако если указан флаг CRYPT_VERIFYCONTEXT , доступ к закрытым ключам не требуется, и пользовательский интерфейс можно обойти. |
|
Создает контейнер ключей с именем, указанным в szContainer. Если szContainer имеет значение NULL, создается контейнер ключей с именем по умолчанию. |
|
По умолчанию ключи и контейнеры ключей хранятся как ключи пользователя. Для базовых поставщиков это означает, что контейнеры ключей пользователей хранятся в профиле пользователя. Доступ к контейнеру ключей, созданному без этого флага администратором, может получить только пользователь, создающий контейнер ключей, и пользователь с правами администрирования.
Windows XP: Доступ к контейнеру ключей, созданному без этого флага администратором, может получить только пользователь, создающий контейнер ключей и учетную запись локальной системы. Доступ к контейнеру ключей, созданному без этого флага пользователем, который не является администратором, может получить только пользователь, создающий контейнер ключей и учетную запись локальной системы. Флаг CRYPT_MACHINE_KEYSET можно объединить со всеми другими флагами, чтобы указать, что контейнер ключей является контейнером ключей компьютера, а поставщик служб CSP обрабатывает его как таковой. Для базовых поставщиков это означает, что ключи хранятся локально на компьютере, на который был создан контейнер ключей. Если контейнер ключей должен быть контейнером компьютера, флаг CRYPT_MACHINE_KEYSET должен использоваться для всех вызовов CryptAcquireContext , ссылающихся на контейнер компьютера. Доступ к контейнеру ключей, созданному с помощью CRYPT_MACHINE_KEYSET администратором, может получить только его создатель и пользователь с правами администратора, если только права доступа к контейнеру не предоставлены с помощью CryptSetProvParam. Windows XP: Контейнер ключей, созданный с помощью CRYPT_MACHINE_KEYSET администратором, может быть доступен только его создателю и учетной записи локальной системы, если только права доступа к контейнеру не предоставлены с помощью CryptSetProvParam. Контейнер ключей, созданный с CRYPT_MACHINE_KEYSET пользователем, который не является администратором, может быть доступен только его создателю и учетной записи локальной системы, если только права доступа к контейнеру не предоставлены с помощью CryptSetProvParam. Флаг CRYPT_MACHINE_KEYSET полезен, если пользователь обращается из службы или учетной записи пользователя, которые не выполнили вход в интерактивном режиме. При создании контейнеров ключей большинство поставщиков служб конфигурации не создают пары открытого и закрытого ключей автоматически. Эти ключи должны быть созданы как отдельный шаг с помощью функции CryptGenKey . |
|
Удалите контейнер ключей , указанный szContainer. Если szContainer имеет значение NULL, контейнер ключей с именем по умолчанию удаляется. Все пары ключей в контейнере ключей также уничтожаются.
Если этот флаг установлен, значение, возвращаемое в phProv , не определено, поэтому после этого не требуется вызывать функцию CryptReleaseContext . |
|
Приложение запрашивает, чтобы поставщик служб CSP не отображал пользовательский интерфейс для этого контекста. Если поставщик служб CSP должен отображать пользовательский интерфейс для работы, вызов завершается сбоем, а код ошибки NTE_SILENT_CONTEXT устанавливается в качестве последней ошибки. Кроме того, если вызовы CryptGenKey выполняются с флагом CRYPT_USER_PROTECTED с контекстом, полученным с флагом CRYPT_SILENT, вызовы завершаются сбоем и CSP NTE_SILENT_CONTEXT.
CRYPT_SILENT предназначена для приложений, для которых поставщик служб CSP не может отображать пользовательский интерфейс. |
|
Получает контекст для CSP смарт-карты, который можно использовать для хэширования и операций с симметричным ключом, но не может использоваться для любой операции, требующей проверки подлинности на смарт-карте с помощью ПИН-кода. Этот тип контекста чаще всего используется для выполнения операций с пустой смарт-картой, таких как установка ПИН-кода с помощью CryptSetProvParam. Этот флаг можно использовать только с CSP смарт-карт.
Windows Server 2003 и Windows XP: Этот флаг не поддерживается. |
Возвращаемое значение
Если функция выполняется успешно, функция возвращает ненулевое значение (TRUE).
Если функция завершается сбоем, она возвращает ноль (FALSE). Чтобы получить дополнительные сведения об ошибке, вызовите Метод GetLastError.
Коды ошибок, предваряемые NTE, создаются конкретным поставщиком служб CSP. Ниже приведены некоторые возможные коды ошибок, определенные в Winerror.h.
Возвращаемый код или значение | Описание |
---|---|
|
Некоторые поставщики служб конфигурации устанавливают эту ошибку, если задано значение флага CRYPT_DELETEKEYSET, а другой поток или процесс использует этот контейнер ключей. |
|
Профиль пользователя не загружен и не найден. Это происходит, когда приложение олицетворяет пользователя, например учетную запись IUSR_ComputerName . |
|
Один из параметров содержит недопустимое значение. Чаще всего это недопустимый указатель. |
|
Во время операции в операционной системе не хватает памяти. |
|
Параметр dwFlags имеет недопустимое значение. |
|
Пароль пользователя изменился с момента шифрования закрытых ключей. |
|
Не удалось открыть контейнер ключей. Распространенная причина этой ошибки заключается в том, что контейнер ключей не существует. Чтобы создать контейнер ключей, вызовите CryptAcquireContext , используя флаг CRYPT_NEWKEYSET. Этот код ошибки также может указывать на то, что доступ к существующему контейнеру ключей запрещен. Права доступа к контейнеру могут быть предоставлены создателем набора ключей с помощью CryptSetProvParam. |
|
Параметру szContainer или szProvider присваивается недопустимое значение. |
|
Значение параметра dwProvType выходит за пределы диапазона. Все типы поставщиков должны быть от 1 до 999 включительно. |
|
Не удалось проверить подпись поставщика DLL. Либо библиотека DLL, либо цифровая подпись были изменены. |
|
Параметр dwFlags CRYPT_NEWKEYSET, но контейнер ключей уже существует. |
|
Контейнер ключа szContainer найден, но поврежден. |
|
Запрошенный поставщик не существует. |
|
Во время операции у поставщика служб CSP не хватает памяти. |
|
DLL-файл поставщика не существует или не находится по текущему пути. |
|
Тип поставщика, указанный параметром dwProvType , поврежден. Эта ошибка может относиться либо к списку CSP по умолчанию пользователя, либо к списку CSP компьютера по умолчанию. |
|
Тип поставщика, указанный параметром dwProvType , не соответствует найденной типу поставщика. Обратите внимание, что эта ошибка может возникать только в том случае, если szProvider указывает фактическое имя CSP. |
|
Для типа поставщика, указанного dwProvType, не существует записи. |
|
Не удалось загрузить или инициализировать DLL-файл поставщика. |
|
Ошибка при загрузке образа DLL-файла перед проверкой его подписи. |
Комментарии
Параметр szContainer указывает имя контейнера, который используется для хранения ключа. Каждый контейнер может содержать один ключ. Если при создании ключей указать имя существующего контейнера, новый ключ перезапишет предыдущий.
Сочетание имени CSP и имени контейнера ключей однозначно идентифицирует один ключ в системе. Если одно приложение пытается изменить контейнер ключей, когда другое приложение использует его, может привести к непредсказуемому поведению.
Если для параметра szContainer задано значение NULL, используется имя контейнера ключа по умолчанию. При таком вызове поставщиков программного обеспечения Майкрософт при каждом вызове функции CryptAcquireContext создается новый контейнер. Однако разные поставщики служб конфигурации могут вести себя по-разному в этом отношении. В частности, поставщик служб CSP может иметь один контейнер по умолчанию, который используется всеми приложениями, обращаюющимися к CSP. Поэтому приложения не должны использовать контейнер ключей по умолчанию для хранения закрытых ключей. Вместо этого либо запретите хранение ключей, передав флаг CRYPT_VERIFYCONTEXT в параметре dwFlags , либо используйте контейнер приложения, который вряд ли будет использоваться другим приложением.
Приложение может получить имя используемого контейнера ключей с помощью функции CryptGetProvParam для чтения значения PP_CONTAINER.
Из соображений производительности рекомендуется задать для параметра szContainerзначение NULL , а параметру dwFlags— значение CRYPT_VERIFYCONTEXT во всех ситуациях, когда не требуется сохраняемый ключ. В частности, рекомендуется задать для параметра szContainerзначение NULL , а параметру dwFlags— значение CRYPT_VERIFYCONTEXT для следующих сценариев:
- Вы создаете хэш.
- Вы создаете симметричный ключ для шифрования или расшифровки данных.
- Вы наследуете симметричный ключ из хэша для шифрования или расшифровки данных.
- Вы проверяете подпись. Можно импортировать открытый ключ из PUBLICKEYBLOB или из сертификата с помощью CryptImportKey или CryptImportPublicKeyInfo. Контекст можно получить с помощью флага CRYPT_VERIFYCONTEXT , если вы планируете импортировать только открытый ключ.
- Вы планируете экспортировать симметричный ключ, но не импортировать его в течение времени существования контекста шифрования. Контекст можно получить с помощью флага CRYPT_VERIFYCONTEXT , если вы планируете импортировать открытый ключ только для двух последних сценариев.
- Вы выполняете операции с закрытым ключом, но не используете сохраненный закрытый ключ, хранящийся в контейнере ключей.
Примеры
В следующем примере показано получение криптографического контекста и доступ к парам открытого и закрытого ключей в контейнере ключей. Если запрошенный контейнер ключей не существует, он создается.
Пример, включающий полный контекст для этого примера, см. в разделе Пример программы C: создание контейнера ключей и создание ключей. Дополнительные примеры см. в разделе Пример программы C: использование CryptAcquireContext.
//-------------------------------------------------------------------
// Declare and initialize variables.
HCRYPTPROV hCryptProv = NULL; // handle for a cryptographic
// provider context
LPCSTR UserName = "MyKeyContainer"; // name of the key container
// to be used
//-------------------------------------------------------------------
// Attempt to acquire a context and a key
// container. The context will use the default CSP
// for the RSA_FULL provider type. DwFlags is set to zero
// to attempt to open an existing key container.
if(CryptAcquireContext(
&hCryptProv, // handle to the CSP
UserName, // container name
NULL, // use the default provider
PROV_RSA_FULL, // provider type
0)) // flag values
{
printf("A cryptographic context with the %s key container \n",
UserName);
printf("has been acquired.\n\n");
}
else
{
//-------------------------------------------------------------------
// An error occurred in acquiring the context. This could mean
// that the key container requested does not exist. In this case,
// the function can be called again to attempt to create a new key
// container. Error codes are defined in Winerror.h.
if (GetLastError() == NTE_BAD_KEYSET)
{
if(CryptAcquireContext(
&hCryptProv,
UserName,
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
printf("A new key container has been created.\n");
}
else
{
printf("Could not create a new key container.\n");
exit(1);
}
}
else
{
printf("A cryptographic service handle could not be "
"acquired.\n");
exit(1);
}
} // End of else.
//-------------------------------------------------------------------
// A cryptographic context and a key container are available. Perform
// any functions that require a cryptographic provider handle.
//-------------------------------------------------------------------
// When the handle is no longer needed, it must be released.
if (CryptReleaseContext(hCryptProv,0))
{
printf("The handle has been released.\n");
}
else
{
printf("The handle could not be released.\n");
}
Примечание
Заголовок wincrypt.h определяет CryptAcquireContext в качестве псевдонима, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора UNICODE. Сочетание использования псевдонима, не зависящий от кодировки, с кодом, не зависящим от кодировки, может привести к несоответствиям, которые приводят к ошибкам компиляции или среды выполнения. Дополнительные сведения см. в разделе Соглашения для прототипов функций.
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Windows XP [только классические приложения] |
Минимальная версия сервера | Windows Server 2003 [только классические приложения] |
Целевая платформа | Windows |
Header | wincrypt.h |
Библиотека | Advapi32.lib |
DLL | Advapi32.dll |