| ||||
| ||||
Ситуация такая. На одном из компьютеров производим экспорт сертификата без закрытого ключа. Устанавливаем этот сертификат на другом компьютере, чтобы впоследствии с помощью этого сертификата шифровать сообщения, которые смогут быть расшифрованны только на 1м компьютере. Но при установке сертификата, он, что понятно, попадает в хранилище не "Личное", а в "Промежуточные центры сертификации" (Что уже не понятно. Почему не в хранилище "Другие пользователи"?). Поэтому, надо открывать хранилище "Промежуточные центры сертификации". В исходниках CSP 2.0 есть такая функция: hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, /* LPCSTR lpszStoreProvider*/ 0, /* DWORD dwMsgAndCertEncodingType*/ 0, /* HCRYPTPROV hCryptProv*/ CERT_STORE_OPEN_EXISTING_FLAG|CERT_STORE_READONLY_FLAG| CERT_SYSTEM_STORE_LOCAL_MACHINE, /* DWORD dwFlags*/ L"MY" /* const void *pvPara*/ ); Как я понимаю, надо менять название хранилища в этой функции? Но на какое? "Other People" и "CA and Root" не подходят, по всей видимости? Или надо менять не только название, но и что-то еще? | ||||
Ответы: | ||||
| ||||
По мнению микрософт личные они и есть личные, и туда сертификаты попадают либо через xenroll.acceptPKCS7 при условии что есть соответствующий закрытый ключ, либо по явному желанию пользователя, когда он в мастере установки явно выбирает "личные". В противном случае в автомате (если нет закрытого ключа) сертификаты идут действительно в промежуточные центры. Справочникa "addressbook" или "other people" по умолчания в виндовсе нет. Он делается при первом запуске почтового клиента. Можно вызывать функцию открытия справочника "addressbook" с флагом его создания, если его нет. | ||||
| ||||
2 kure Тогда понятно, почему при даже явном указании "Другие пользователи" сертификат туда не устанавливался. А как же открыть хранилище "Промежуточные центры сертификации"? Чтобы использовать сертификат оттуда? Это и есть "Adressbook", что ли? Или это невозможно? hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, /* LPCSTR lpszStoreProvider*/ 0, /* DWORD dwMsgAndCertEncodingType*/ 0, /* HCRYPTPROV hCryptProv*/ CERT_STORE_OPEN_EXISTING_FLAG|CERT_STORE_READONLY_FLAG| CERT_SYSTEM_STORE_LOCAL_MACHINE, /* DWORD dwFlags*/ L"adressbook" /* const void *pvPara*/ ); Так? | ||||
| ||||
Посмотрите в МSDN ссылку "System Store Locations" в описании CertOpenStore. Там все справочники описаны. "Промежуточные центры" это "CA". Но зачем вам сертификаты других пользоватлей держать в нем? | ||||
| ||||
Т.к. эти сертификаты устанавливаются туда по умолчанию. Иначе - либо самим выбирать в какое хранилище ставить, либо из своей программы предоставлять возможность установки сертификата. А еще такой вопрос - можно ли с помощью КриптоПро CSP 2.0 шифровать на таких сертификатах? Нет ли ограничений? | ||||
| ||||
Процесс шифрования от размещения сертификата не зависит (хоть в файле, хоть в справочнике). Функции шифрования из CryptoAPI нужен контекст сертификата, а уж вы сами его подготовите. | ||||
| ||||
Так ведь в этом сертификате не будет закрытого ключа! Вот, например, вызываю csptest2_0.exe с такими аргументами: -ep -in c:\file.in -out c:\file.out -my Cert -encrypt, где Cert - как раз и есть тот сертификат без закрытого ключа. Вопрос-то в чем: почему надо обязательно шифровать на сертификате с закрытым ключем? Можно, конечно, делать так: -ep -in c:\file.in -out c:\file.out -my CertPK -rcp Cert -encrypt, где Cert - сертификат без закрытого ключа, CertPK - с ним, соответственно. Но ведь это лишнее действие... | ||||
| ||||
Не бывает в сертификатах закрытого ключа. В справочнике к сертификату может быть добавлен атрибут - ссылка на закрытый ключ. А тест берет сертификаты из "личных". При шифровании свой закрытый ключ не нужен (если специально не выбирать другой режим шифрования). Нужен только открытых ключ получателя. А при расшифровании нужен как раз закрытый ключ получателя. | ||||
| ||||
Спасибо, осознал. Но остался вопрос - как называется справочник "Другие пользователи"? В MSDN есть упоминание только про MY, CA, Root, Trust. И использование функции CertFindCertificateInStore() - как искать не по имени владельца, а по серийному номеру сертификата? Использовать ключ CERT_FIND_CERT_ID и структуру CERT_ID? Но в требованиях указано, что это работает только под 2000, ХР. Есть ли иные способы поиска сертификата (просто при поиске по имени, может возникнуть неоднозначность, если есть два сертификата с одинаковыми именами)? | ||||
| ||||
Локализованное имя хранилища "Другие пользователи" соответствует хранилищу "AddressBook". | ||||
| ||||
А по поводу поиска сертификата в хранилище в "старых" Windows - можно просто перебрать все сертификаты и выбрать нужный. | ||||
| ||||
2 Седов Роман Ясно. "А по поводу поиска сертификата в хранилище в "старых" Windows - можно просто перебрать все сертификаты и выбрать нужный." А как функция CertFindCertificateInStore() реагирует, если находит два одинаковый сертификата с одинаковыми именами? Возвращает дескриптор на первый попавщийся сертификат? Тогда как я смогу выбрать другой, с иным серийным номером? | ||||
| ||||
Читайте внимательнее MSDN Library... У функции есть параметр "pPrevCertContext"! | ||||