| ||||
| ||||
Здравствуйте. Подскажите, пожалуйста, что можно сделать в сл. ситуации. ...HCERTSTORE* hSystemStore, HCRYPTPROV* hProv, PCCERT_CONTEXT* pCertContext.... Для того, чтобы получить HCRYPTPROV, при вызове нужно явно задать имя контейнера. Пользователю доступны около сотни контейнеров. в сл. примере ищу сертификат, с именем lpCertSubjectUnicode. if (!CryptAcquireContext(hProv, strContainerName,strCSPName,dwCSPType , 0)) { ::MessageBox(NULL,"CryptAcquireContext ERROR:01 ", NULL,MB_OK|MB_ICONERROR); return FALSE; } if (!(*hSystemStore = CertOpenSystemStore(*hProv, "MY")))//"MY" { ::MessageBox(NULL,"CertOpenSystemStore ERROR: can not open.", NULL,MB_OK|MB_ICONERROR); return FALSE; } *pCertContext=CertFindCertificateInStore (*hSystemStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, lpCertSubjectUnicode , NULL); ...........Получается сл. ситуация. Вне зависимости от имени контейнера (указанного при CryptAcquireContext (...strContainerName...), с помощью CertFindCertificateInStore могу получить любой сертификат (для данного пользователя и данного криптопровайдера). Даже, если он не лежит в контейнере strContainerName... так получается?! Тогда для работы с любым сертификатом в Store могу указать любое lpCertSubjectUnicode. И буду работать с этим сертификатом. Тогда значение имени контейнера (CryptAcquireContext (...strContainerName...), сводится к нулю. Могу просто указать любой контейнер для данного пользователя (имя возьму из ветки реестра), а работать все равно с другими. Получается, так? спасибо. | ||||
Ответы: | ||||
| ||||
Не вполне понятный вопрос. Если Вы хотите самостоятельно открывать контейнер (по имени) и сертификат - пожалуйста. Но, при этом Вы и заботитесь об их соответствии друг другу. Не получится использовать сертификат со значением открытого ключа, которое не соответствует закрытому ключу в контейнере. Собственно, я уже указывал Вам, как получить хендл контейнера по сертификату, открытому из хранилища сертификатов (или из файла сертификата при условии, что в хранилище сертификат установлен). При этом имя контейнера не нужно знать. Весь смысл высокоуровневых функций в том, что функциям задаются только сертификаты, а они уже самостоятельно, когда нужно, работают с контейнерами. | ||||
| ||||
да получается так, что я могу открыть один контейнер - CryptAcquireContext,, а работать с сертификатом из другого совершенно контейнера, указав, например, владельца сертификата в функцию CertFindCertificateInStore... | ||||
| ||||
и не подскажите, пожалуйста, каким образом открыть из файла сертификат (функция и т.д). | ||||
| ||||
Можно, но зачем? А если не требуется доступ к секретному ключу в контейнере, можно CryptAcquireContext вызвать с флажком CRYPT_VERIFYCONTEXT и с указанием только типа CSP, например, CryptAcquireContext( &hProv, NULL, NULL, 75, CRYPT_VERIFYCONTEXT) По второму. DWORD dwCertLen; BYTE *bCert; PCCERT_CONTEXT pCert = 0; dwCertLen = ...//размер файла сертификата hFile=fopen("...","rb"); fread(bCert,1,dwCertLen,hFile); fclose(hFile); pCert = CertCreateCertificateContext (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, bCert, dwCertLen); | ||||