Форум КриптоПро
»
Устаревшие продукты
»
КриптоПро CSP 3.0
»
Проблема при использовании функции CertGetCertificateContextProperty
Казакова |
|
Статус: Новичок Группы: Участники
|
Добрый день. Вопрос такой. Используется функция Отличие в сертификатах: при просмотре через оснастку во втором случае на первой закладке «Общие» отсутствует свойство «Есть закрытый ключ, соответствующий этому сертификату». Собственно вопросы: |
|
|
Василий Дементьев |
|
Статус: Администратор Группы: Администраторы, Участники Поблагодарили: 5 раз в 4 постах |
Уточнение. А какое именно свойство Вы хотите получить (т.е. чему равно значение dwPropId)? |
|
WWW |
Kirill Sobolev |
|
Статус: Сотрудник Группы: Участники Поблагодарили: 177 раз в 168 постах |
Если речь идет о CERT_KEY_PROV_INFO_PROP_ID, судя по вопросам, то |
Техническую поддержку оказываем тут |
|
|
WWW |
Казакова |
|
Статус: Новичок Группы: Участники
|
Василий Дементьев написал: Уточнение. А какое именно свойство Вы хотите получить (т.е. чему равно значение dwPropId)? dwPropId = CERT_KEY_PROV_INFO_PROP_ID |
|
|
Игорь М. |
|
Статус: Новичок Группы: Участники
|
Василий Дементьев написал: Уточнение. А какое именно свойство Вы хотите получить (т.е. чему равно значение dwPropId)? Некоторое уточнение. if(!(CertGetCertificateContextProperty( //——————————————- |
|
|
Игорь М. |
|
Статус: Новичок Группы: Участники
|
Отредактировано пользователем 10 декабря 2009 г. 15:05:47(UTC) |
|
|
Василий Дементьев |
|
Статус: Администратор Группы: Администраторы, Участники Поблагодарили: 5 раз в 4 постах |
Для поставленной задачи вообще не нужно вызывать эту функцию. Алгоритм открытого ключа сертификата имеется в структуре pCertContext. pCertContext->pCertInfo.SubjectPublicKeyInfo.Algorithm Это поле типа CRYPT_ALGORITHM_IDENTIFIER, в котором есть строка — идентификатор алгоритма. Для алгоритмов ГОСТ и сертификатов КриптоПро CSP значение идентификатора алгоритма начинается с 1.2.643.2.2 Отредактировано пользователем 10 декабря 2009 г. 15:48:16(UTC) |
|
WWW |
Пользователи, просматривающие эту тему |
Guest |
Форум КриптоПро
»
Устаревшие продукты
»
КриптоПро CSP 3.0
»
Проблема при использовании функции CertGetCertificateContextProperty
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
I got a sample code from MSDN (http://msdn2.microsoft.com/en-us/library/aa382363.aspx)
I generate a Win32 console application project in VisualStudio 2005 and copy the code into my main.cpp. But when I compiled it, I got the following errors:
1>Compiling…
1>main.cpp
1>.\main.cpp(55) : error C2664: ‘CertOpenSystemStoreW’ : cannot convert parameter 2 from ‘char [256]’ to ‘LPCWSTR’
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>.\main.cpp(103) : error C2664: ‘CertGetNameStringW’ : cannot convert parameter 5 from ‘char [256]’ to ‘LPWSTR’
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>.\main.cpp(317) : error C3861: ‘_ftprintf’: identifier not found
1>.\main.cpp(318) : error C3861: ‘_ftprintf’: identifier not found
1>.\main.cpp(319) : error C3861: ‘_ftprintf’: identifier not found
1>.\main.cpp(320) : error C3861: ‘_ftprintf’: identifier not found
1>Build log was saved at «file://d:\C++\cryptoAPI\Creating a Key Container and Generating\Creating a Key Container and Generating\Debug\BuildLog.htm»
1>Creating a Key Container and Generating — 6 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Does anyone have some ideas? thank you in advance!
this is the source code:
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <cryptuiapi.h>
#pragma comment (lib, «crypt32.lib»)
#pragma comment (lib, «cryptui.lib»)
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);
void main(void)
{
//——————————————————————-
// Copyright (c) Microsoft Corporation. All rights reserved.
// This program lists all of the certificates in a system certificate
// store and all of the property identifier numbers of those
// certificates. It also demonstrates the use of two
// UI functions. One, CryptUIDlgSelectCertificateFromStore,
// displays the certificates in a store
// and allows the user to select one of them,
// The other, CryptUIDlgViewContext,
// displays the contents of a single certificate.
//——————————————————————-
// Declare and initialize variables.
HCERTSTORE hCertStore;
PCCERT_CONTEXT pCertContext=NULL;
char pszNameString[256];
char pszStoreName[256];
void* pvData;
DWORD cbData;
DWORD dwPropId = 0;
// Zero must be used on the first
// call to the function. After that,
// the last returned property identifier is passed.
//——————————————————————-
// Begin processing and Get the name of the system certificate store
// to be enumerated. Output here is to stderr so that the program
// can be run from the command line and stdout can be redirected
// to a file.
fprintf(stderr,»Please enter the store name:»);
fgets(pszStoreName, 256, stdin);
fprintf(stderr,»The store name is %s .\n»,pszStoreName);
//——————————————————————-
// Open a system certificate store.
if ( hCertStore = CertOpenSystemStore(
NULL,
pszStoreName))
{
fprintf(stderr,»The %s store has been opened. \n»,
pszStoreName);
}
else
{
// If the store was not opened, exit to an error routine.
MyHandleError(«The store was not opened.»);
}
//——————————————————————-
// Use CertEnumCertificatesInStore to get the certificates
// from the open store. pCertContext must be reset to
// NULL to retrieve the first certificate in the store.
// pCertContext = NULL;
while(pCertContext= CertEnumCertificatesInStore(
hCertStore,
pCertContext))
{
//——————————————————————-
// A certificate was retrieved. Continue.
//——————————————————————-
// Display the certificate.
if ( CryptUIDlgViewContext(
CERT_STORE_CERTIFICATE_CONTEXT,
pCertContext,
NULL,
NULL,
0,
NULL))
{
// printf(«OK\n»);
}
else
{
MyHandleError(«UI failed.»);
}
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
pszNameString,
128))
{
printf(«\nCertificate for %s \n»,pszNameString);
}
else
fprintf(stderr,»CertGetName failed. \n»);
//——————————————————————-
// Loop to find all of the property identifiers for the specified
// certificate. The loop continues until
// CertEnumCertificateContextProperties returns zero.
while(dwPropId = CertEnumCertificateContextProperties(
pCertContext, // The context whose properties are to be listed.
dwPropId)) // Number of the last property found.
// This must be zero to find the first
// property identifier.
{
//——————————————————————-
// When the loop is executed, a property identifier has been found.
// Print the property number.
printf(«Property # %d found->», dwPropId);
//——————————————————————-
// Indicate the kind of property found.
switch(dwPropId)
{
case CERT_FRIENDLY_NAME_PROP_ID:
{
printf(«Friendly name: «);
break;
}
case CERT_SIGNATURE_HASH_PROP_ID:
{
printf(«Signature hash identifier «);
break;
}
case CERT_KEY_PROV_HANDLE_PROP_ID:
{
printf(«KEY PROVE HANDLE»);
break;
}
case CERT_KEY_PROV_INFO_PROP_ID:
{
printf(«KEY PROV INFO PROP ID «);
break;
}
case CERT_SHA1_HASH_PROP_ID:
{
printf(«SHA1 HASH identifier»);
break;
}
case CERT_MD5_HASH_PROP_ID:
{
printf(«md5 hash identifier «);
break;
}
case CERT_KEY_CONTEXT_PROP_ID:
{
printf(«KEY CONTEXT PROP identifier»);
break;
}
case CERT_KEY_SPEC_PROP_ID:
{
printf(«KEY SPEC PROP identifier»);
break;
}
case CERT_ENHKEY_USAGE_PROP_ID:
{
printf(«ENHKEY USAGE PROP identifier»);
break;
}
case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
{
printf(«NEXT UPDATE LOCATION PROP identifier»);
break;
}
case CERT_PVK_FILE_PROP_ID:
{
printf(«PVK FILE PROP identifier «);
break;
}
case CERT_DESCRIPTION_PROP_ID:
{
printf(«DESCRIPTION PROP identifier «);
break;
}
case CERT_ACCESS_STATE_PROP_ID:
{
printf(«ACCESS STATE PROP identifier «);
break;
}
case CERT_SMART_CARD_DATA_PROP_ID:
{
printf(«SMART_CARD DATA PROP identifier «);
break;
}
case CERT_EFS_PROP_ID:
{
printf(«EFS PROP identifier «);
break;
}
case CERT_FORTEZZA_DATA_PROP_ID:
{
printf(«FORTEZZA DATA PROP identifier «);
break;
}
case CERT_ARCHIVED_PROP_ID:
{
printf(«ARCHIVED PROP identifier «);
break;
}
case CERT_KEY_IDENTIFIER_PROP_ID:
{
printf(«KEY IDENTIFIER PROP identifier «);
break;
}
case CERT_AUTO_ENROLL_PROP_ID:
{
printf(«AUTO ENROLL identifier. «);
break;
}
} // End switch.
//——————————————————————-
// Retrieve information on the property by first getting the
// property size.
// For more information, see CertGetCertificateContextProperty.
if(CertGetCertificateContextProperty(
pCertContext,
dwPropId ,
NULL,
&cbData))
{
// Continue.
}
else
{
// If the first call to the function failed,
// exit to an error routine.
MyHandleError(«Call #1 to GetCertContextProperty failed.»);
}
//——————————————————————-
// The call succeeded. Use the size to allocate memory
// for the property.
if(pvData = (void*)malloc(cbData))
{
// Memory is allocated. Continue.
}
else
{
// If memory allocation failed, exit to an error routine.
MyHandleError(«Memory allocation failed.»);
}
//—————————————————————-
// Allocation succeeded. Retrieve the property data.
if(CertGetCertificateContextProperty(
pCertContext,
dwPropId,
pvData,
&cbData))
{
// The data has been retrieved. Continue.
}
else
{
// If an error occurred in the second call,
// exit to an error routine.
MyHandleError(«Call #2 failed.»);
}
//—————————————————————
// Show the results.
printf(«The Property Content is %d \n», pvData);
//—————————————————————-
// Free the certificate context property memory.
free(pvData);
} // End inner while.
} // End outer while.
//——————————————————————-
// Select a new certificate by using the user interface.
if(!(pCertContext = CryptUIDlgSelectCertificateFromStore(
hCertStore,
NULL,
NULL,
NULL,
CRYPTUI_SELECT_LOCATION_COLUMN,
0,
NULL)))
{
MyHandleError(«Select UI failed.» );
}
//——————————————————————-
// Clean up.
CertFreeCertificateContext(pCertContext);
CertCloseStore(hCertStore,0);
printf(«The function completed successfully. \n»);
} // End of main.
void MyHandleError(LPTSTR psz)
{
_ftprintf(stderr, TEXT(«An error occurred in the program. \n»));
_ftprintf(stderr, TEXT(«%s\n»), psz);
_ftprintf(stderr, TEXT(«Error number %x.\n»), GetLastError());
_ftprintf(stderr, TEXT(«Program terminating. \n»));
exit(1);
} // End of MyHandleError.
- Remove From My Forums
-
Question
-
Hi,
I am trying to use CertGetCertificateContextProperty to get CERT_ROOT_PROGRAM_CERT_POLICIES_PROP_ID to read the OID’s and use the CertSetCertificateContextProperty to add OID’s that are missing.
I have imported the required DLL’s.
Could someone provide sample code of how to get the values and put them in the structures. The CERT_POLICIES_INFO and CERT_POLICY_INFO structures have been defined. Also how do I use CryptDecodeObject and CryptEncodeObject.
-
Edited by
Tuesday, April 17, 2012 12:06 AM
-
Moved by
Alan_chen
Tuesday, April 17, 2012 3:28 AM
(From:Visual C# General) -
Moved by
Yi Feng Li
Wednesday, April 18, 2012 5:07 AM
(From:Visual C++ Language)
-
Edited by
Answers
-
This issue has been resolved, I was miss understanding the documentation. What I needed to do was first Decode the Data to get the Policy Structure.
-
Marked as answer by
Paul Caesar
Thursday, April 19, 2012 11:38 PM
-
Marked as answer by
I tried to get EC private key from cert which in certificate store by CNG API. First, I call CertGetCertificateContextProperty()
to get private key handle with CERT_KEY_CONTEXT_PROP_ID
property, but it always return false. I’m sure that the cert has private key.
Code:
wchar_t wMY_CERT_NAME[100];
HCERTSTORE hCertStore = NULL;
PCCERT_CONTEXT pSignerCert = NULL;
NCRYPT_KEY_HANDLE hKey = NULL;
const int buffsize = 4999;
DWORD len = buffsize;
char buff[buffsize];
// Open the certificate store.
if (!(hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
CERT_STORE_NAME)))
{
MyHandleError(const_cast<LPTSTR>("The MY store could not be opened."));
}
swprintf(wMY_CERT_NAME, 100, L"%hs", MY_CERT_NAME);
if (pSignerCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
wMY_CERT_NAME,
NULL))
{
//continue
}
if (CertGetCertificateContextProperty(
pSignerCert,
CERT_KEY_CONTEXT_PROP_ID,
buff,
&len))
{
auto ckc = (CERT_KEY_CONTEXT *)buff;
hKey = ckc->hNCryptKey;
}
else {
wprintf(L"**** GetCertContextProperty failed.\n");
}
Then, I tried to do the same step but read from a .pfx file like this page. It return true and get private key successfully. Why cert in certificate store doesn’t have CERT_KEY_CONTEXT_PROP_ID
property?
MurCode
- Форумы
- Поиск
- О проекте
еще раз про сертификаты
sergq
Дата: 07.05.2016 01:11:20
Здравствуйте.
слегка недопонимаю про сертификаты и контейнеры
выбираю свой сертификат через CryptUIDlgSelectCertificateFromStore(
теперь пытаюсь сохранить сертификат в файл.
получаю KeyProvInfo
(CertGetCertificateContextProperty(self.pCertContext,CERT_KEY_PROV_INFO_PROP_ID,KeyProvInfo,@cbHash))
читаю на всякий случай имя контейнера KeyProvInfo.pwszContainerName
затем успешно
CryptAcquireContext(@hProv,PChar(CertContName),nil,PROV_GOST_2001_DH,0)
и далее
CryptGetUserKey(hProv,AT_KEYEXCHANGE,@hKey)
(CryptGetKeyParam(hKey,KP_CERTIFICATE,nil,@cbCertBlob,0)
и на последней строчке получаю 0x8010002C требуемый сертификат не существует.
Иду в криптопро. Просмотреть сертификаты в контейнере. выводится список контейнеров. и в нем есть тот, который был сохранен после CertGetCertificateContextProperty. криптопро говорит, что сертификаты в контейнере нет. но в certmgr.msc он есть.
Недопонимаю этого момента. он ведь есть в системе, но его по всей видимости нет в контейнере закрытого ключа? контейнер закрытого ключа по всей видимости в криптопро?
Запутался.
На другой машине в аналогичной ситуации сертификат успешно сохраняется в файл.
Ghost Writer
Дата: 07.05.2016 01:38:08
sergq,
сохранить сертификат требуется из хранилища сертификатов или из ключевого контейнера?
Если сертификат есть в хранилище сертификатов (в certmgr.msc), то это не значит, что он установлен в контейнер.
Если КриптоПро говорит, что сертификата в контейнере нет, значит его нет. Чтобы был, надо установить ).
Галочка на скрине в старых версиях КриптоПро CSP отсутствует.
sergq
Дата: 07.05.2016 19:19:59
Ghost Writer,
Вот тут у меня непонятка и возникла.
Те получается когда я сертификат и ключи устанавливаю стандартным мастером он ставится в хранилище сертификатов?
Переносил я все это дело через мастер certmgr.msc.
Недопонимаю я связь между хранилищем сертификатов и крипто про. Ведь в контексте сертификата есть наименоваение контейнера. Реестр. Тола причем тут криптопро и его контейнер. Который равен KeyProvInfo.pwszContainerName
Или же все сертификаты хранятся в хранилище сертификатов и как допопция в контейнере криптопро ? Скорее всего так.
А хотел я получить сертификат и не важно откуда. Из ключевого контейнера или же из системного хранилища сертификатов.
Ghost Writer
Дата: 07.05.2016 22:26:33
sergq |
---|
Те получается когда я сертификат и ключи устанавливаю стандартным мастером он ставится в хранилище сертификатов? |
Да.
sergq |
---|
Ведь в контексте сертификата есть наименоваение контейнера. |
Наименование контейнера, получаемое с помощью CertGetCertificateContextProperty, не содержится в контексте сертификата. Читай про CertGetCertificateContextProperty
Remarks |
---|
Properties are not stored inside a certificate. Typically, they are associated with a certificate after the certificate response is received and then saved with the certificate in the store. |
При установке сертификата КриптоПро связывает его с выбранным тобой контейнером CertSetCertificateContextProperty( … CERT_KEY_PROV_INFO_PROP_ID… )
sergq |
---|
Или же все сертификаты хранятся в хранилище сертификатов и как допопция в контейнере криптопро ? |
КриптоПро и контейнер (ключевой контейнер!) — это разные вещи.
sergq |
---|
А хотел я получить сертификат и не важно откуда. |
Так ведь уже получил на этапе CryptUIDlgSelectCertificateFromStore
sergq
Дата: 08.05.2016 18:53:08
Ghost Writer | ||
---|---|---|
Наименование контейнера, получаемое с помощью CertGetCertificateContextProperty, не содержится в контексте сертификата. Читай про CertGetCertificateContextProperty |
Чуток неверно выразился. наименование контейнера получаю через CertGetCertificateContextProperty,CERT_KEY_PROV_INFO_PROP_ID. И оно верно. если смотреть из панели криптопро
Ghost Writer | ||
---|---|---|
КриптоПро и контейнер (ключевой контейнер!) — это разные вещи. |
Тут еще недопонял )))
Ghost Writer | ||
---|---|---|
Так ведь уже получил на этапе CryptUIDlgSelectCertificateFromStore |
да. получил. но вот сохранение его в файл с использованием
CryptGetUserKey(hProv,AT_KEYEXCHANGE,@hKey)
(CryptGetKeyParam(hKey,KP_CERTIFICATE,nil,@cbCertBlob,0)
обламывается с вышеприведенной ошибкой
вот собственно и силюсь понять, почему в принципе одна и та же подпись на разных компьютерах ведет себя в данном случае по разному. в одном успешно выгружается в файл сертификат, в другом ошибка
Ghost Writer
Дата: 08.05.2016 20:12:36
sergq |
---|
но вот сохранение его в файл с использованием
CryptGetUserKey(hProv,AT_KEYEXCHANGE,@hKey)
(CryptGetKeyParam(hKey,KP_CERTIFICATE,nil,@cbCertBlob,0)
|
это по твоему сохранение?
этими строчками ты снова пытаешься достать сертификат (который уже достал их хранилища) из ключевого контейнера. Но в контейнере у тебя сертификата нет.
Чтобы вода была горячей — ее надо подогреть. А чтобы сертификат был в контейнере — его надо туда установить.
Еще раз повторю: сертификат ты уже получил с помощью CryptUIDlgSelectCertificateFromStore. Пример:
CertContext := CryptUIDlgSelectCertificateFromStore;
Вот и сохраняй CertContext в файл.
sergq
Дата: 09.05.2016 02:59:11
Ghost Writer,
угу (
pCertContextTemp^.pbCertEncoded
по поводу сохранения в файл имелось ввиду это. не дописал )
CryptGetKeyParam(hKey,KP_CERTIFICATE,nil,@cbCertBlob,0)
CryptGetKeyParam(hKey,KP_CERTIFICATE,pbCertBlob.Memory,@cbCertBlob,0)
те это я пытаюсь получить сертификат из контейнера?
а это
CertContext := CryptUIDlgSelectCertificateFromStore;
из хранилища?