03.09.2007 16:11:54Создание сертификата с экспортируемым приватным ключем Ответов: 2
Dmitry
Привет!

Создаю серификат через
CertCreateSelfSignCertificate(NULL,&SubjNameBlob,0,NULL,&alg,(PSYSTEMTIME)&timeFrom,(PSYSTEMTIME)&timeTo,&certExtensions);

Здесь HCRYPTPROV и PCRYPT_KEY_PROV_INFO == NULL, по MSDN:
PROV_RSA_FULL provider type, the default key specification, AT_SIGNATURE, and a newly-created key container with a unique container name are used.


Все нормально, только приватный ключ не экспортируемый.

Пытаюсь создать контейнер и сгенерировать ключевую пару с возможностью экспорта приватной части:

...
srand( (unsigned)time( NULL ) );
TCHAR strContainerBuf[64] = {0};
_itot(rand(),strContainerBuf,10);
strContainer = strContainerBuf;

CryptAcquireContext(&hNewProv,(LPCTSTR)strContainer, NULL,PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET);
CryptGenKey(hNewProv,AT_SIGNATURE,CRYPT_EXPORTABLE,&hKey);
...

Затем вызываю CreateSelfSignCertificate с первым параметром hNewProv.

После экспорта в хранилище серификата, приватный ключ видно, однако на попытке CryptAcquireCertificatePrivateKey на него,
пишет что не может найти приватной части. :(


Такая же ботва если использовать CryptSignAndEncodeCertificate для создания сертификата:
В этом случае, уже после создание PCCERT_CONTEXT:

...
CRYPT_KEY_PROV_INFO KeyProvInfo; ZeroMemory((PVOID)&KeyProvInfo, sizeof(CRYPT_KEY_PROV_INFO));

KeyProvInfo.pwszContainerName = (LPWSTR)(LPCWSTR)strContainer;
KeyProvInfo.pwszProvName = NULL;
KeyProvInfo.dwProvType = PROV_RSA_FULL;
KeyProvInfo.dwFlags = 0;
KeyProvInfo.dwKeySpec = AT_SIGNATURE;

CertSetCertificateContextProperty(newCert,CERT_KEY_PROV_INFO_PROP_ID,0,(const void *) &KeyProvInfo);
...

Может необходимо выполнить ещё какие то действия?
 
Ответы:
03.09.2007 17:51:57Dmitry
Создать SelfSign удалось с exportable ключем (нужно вместо MS_DEF_PROV использовать например MS_ENHANCED_PROV),
а вот потом связать подписанный SelfSign сертификатом новый, созданный через CryptSignAndEncodeCertificate нет.
Тоже в свойcтвах сертификата ключ есть, а при попытке экспорта пишет что не может его найди.
Делаю так:

newCert = CertCreateCertificateContext(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, &encCert.front(), encCertLen);


CRYPT_KEY_PROV_INFO KeyProvInfo; ZeroMemory((PVOID)&KeyProvInfo, sizeof(CRYPT_KEY_PROV_INFO));

KeyProvInfo.pwszContainerName = (LPWSTR)(LPCWSTR)strContainer;
KeyProvInfo.pwszProvName = MS_ENHANCED_PROV;
KeyProvInfo.dwProvType = PROV_RSA_FULL;
KeyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
KeyProvInfo.dwKeySpec = AT_SIGNATURE;

CertSetCertificateContextProperty(newCert,CERT_KEY_PROV_INFO_PROP_ID,0,(const void *) &KeyProvInfo);

03.09.2007 18:34:06Dmitry
Тема закрыта.

Станно, но проблема была здесь(strContainer - CString, сборка Unicode):

KeyProvInfo.pwszContainerName = (LPWSTR)(LPCWSTR)strContainer;