| ||||
| ||||
Здравствуйте. Из сертификата открытого ключа выделяю открытый ключ. В каком именно виде он передается в функцию CPImportKey(...), а также что такое "magic", который как я знаю добавляется в импортируемый открытый ключ. Заранее благодарю. | ||||
Ответы: | ||||
| ||||
Не совсем понятно, зачем импортировать ф-ей CPImportKey ключ, полученный из сертификата. Если есть сертификат, то ф-ей CryptImportPublicKeyInfoEx или CryptImportPublicKeyInfo сразу получаем хендл открытого ключа, который можно использовать в функциях CryptoAPI. | ||||
| ||||
Не спорю можно и функциями CryptImportPublicKeyInfoEx() и CryptImportPublicKeyInfo(), однако эти функции высокого уровня, а мне необходимо реализовать проверку ЭЦП низкоуровневыми функциями, что требует самостоятельного приведения открытого ключа к тому виду, в котором он передается в функции криптопровайдера. | ||||
| ||||
Извините за назойливость, но все- таки можно узнать ответы на предыдущие вопросы? | ||||
| ||||
Можно уточнить, всё-таки, почему нужны низкоуровневые функции? | ||||
| ||||
Использование низкоуровневых функций необходимо для возможности одновременного использования трех криптопровайдеров /а именно КриптоПро, Сигнал-Ком и VipNet/ на одном компьютере. А так как функции CryptoApi обращаются к криптопровайдеру, который был установлен последним, то использование высокоуровневых функций неприемлемо. Ранее данная проблема обсуждалась на Вашем форуме, но в этих топиках я ничего полезного не подчерпнул. | ||||
| ||||
Можно прокомментировать: > А так как функции CryptoApi обращаются к криптопровайдеру, который был установлен последним... Укажите, пожалуйста, пример последовательности вызовов высокоуровневых функций CryptoAPI (названия функций и параметры), которые неправильно работают при наличии нескольких CSP. А также исходные данные - сертификат читается из хранилища (в этом случае - есть ли ссылка на секретный ключ), или из файла, или из сообщения; в каком формате сообщение и каким ПО подписанное сообщение было получено. | ||||
| ||||
Здравствуйте Василий. Итак по порядку: Сертификат выделяется из сообщения формата PKCS#7. Сообщение подписывается 3 раза разичными CSP (КриптоПро, Сигнал-Ком и VipNet). И соответственно при попытке проверить подпись созданную CSP Крипто-Про при установленном последним /к примеру/ CSP Signal-Com, происходит ошибка верификации подписи, и наоборот. Примеры использования высокоуровнеевых функций взяты из MSDN, единственное что в них было измененно, так это значения входных параметров, на значения соответсвующие российским CSP. | ||||
| ||||
Раз Вы не хотите указать названия вызываемых функций и их параметры - я вряд ли Вам помогу. | ||||
| ||||
Здравствуйте. Почему же не хочу, я просто не вижу в этом смысла, но если Вам это так необходимо, то привожу в качестве примера кусок кода, который не работает при нескольких установленных CSP. / порядок устанвки: 1)VipNet 2)Крипто-Про 3)Signal-Com / PCCERT_CONTEXT certContext = NULL; CRYPT_VERIFY_MESSAGE_PARA VerifyPara; HCRYPTPROV hCryptProv = NULL; DWORD cbMessage; BYTE *pbMessage = NULL; DWORD cbBuffer; BYTE *pbBuffer = NULL; while (1) { if (CryptAcquireContext(&hCryptProv, NULL, "Crypto-Pro GOST R 34.10-94 Cryptographic Service Provider", 71, CRYPT_VERIFYCONTEXT)) break; cbMessage = FileSize(src_file); if (!(pbMessage = (BYTE *)malloc(cbMessage))) break; if (!ReadFromFile(src_file, &pbMessage, cbMessage, 0)) break; memset(&VerifyPara, 0, sizeof(CRYPT_VERIFY_MESSAGE_PARA)); VerifyPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA); VerifyPara.dwMsgAndCertEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; VerifyPara.hCryptProv = hCryptProv; if (!CryptVerifyMessageSignature(&VerifyPara, 0, pbMessage, cbMessage, NULL, &cbBuffer, &certContext)) break; if(!(pbBuffer = (unsigned char*)malloc(cbBuffer))) break; if (!CryptVerifyMessageSignature(&VerifyPara, 0, pbMessage, cbMessage, pbBuffer, &cbBuffer, &certContext)) break; break; } ... if (pbBuffer) free(pbBuffer); if (pbMessage) free(pbMessage); if (certContext) CertFreeCertificateContext(certContext); if (hCryptProv) CryptReleaseContext(hCryptProv, 0); | ||||
| ||||
Также появилась проблема с использованием библиотек Крипто-Про версии 3. Подключение и загрузка функции CPAcquireContext происходит удачно, но при попытке использования возникает ошибка: "Ошибка 2148073501: Библиотека поставщика проинициализирована неправильно." Хотя тот же код с библиотеками Крипто-Про 2-ой версии работает корректно. Вот текст кода: typedef BOOL (WINAPI *Acquire)(HCRYPTPROV*,char*,DWORD, PVTableProvStruc*); ... Acquire AcquireContext; AcquireContext = (Acquire) GetProcAddress(hinstLib, TEXT("CPAcquireContext")); ... if (AcquireContext(&hCreateContainer, NULL, CRYPT_VERIFYCONTEXT, &pVTable)) std::cout<<"Function success\n"; else { std::cout<<DefLastError()<<"\n"; std::cout<<"Function faild\n"; } | ||||
| ||||
а что в pVTable? | ||||
| ||||
Здравствуйте maxdm. Забыл скопировать назначения параметров в pVTable. pVTable.Version = 1; pVTable.FuncVerifyImage = NULL; pVTable.FuncReturnhWnd = NULL; остальные элементы структуры я не заполняю. | ||||
| ||||
>остальные элементы структуры я не заполняю. А зря :) | ||||
| ||||
Я просто посмотрел тестовые утилитки Крипто-Про, где они заполняют те же параметры что я указал выше, поэтому я решил что этого достаточно. Если нет, то можите указать примерные значения остальных параметров данной структуры. | ||||
| ||||
Нужно имя и тип провайдера указывать, и версию 3. typedef struct VTableProvStruc { DWORD Version; FARPROC FuncVerifyImage; FARPROC FuncReturnhWnd; DWORD dwProvType; BYTE* pbContextInfo; DWORD cbContextInfo; LPSTR pszProvName; } VTableProvStruc, *PVTableProvStruc; А не проще использовать CryptAcquireContext? | ||||
| ||||
Здравствуйте maxdm. Спасибо за консультацию по параметрам структуры PVTableProvStruc, однако это не помогло. Возникает та же ошибка. Возможно есть еще какая - либо причина? | ||||
| ||||
А может причина в том, что Signal-Com мешает работе КриптоПро? Более подробно об этом можно прочитать тут http://www.signal-com.ru/ru/forum/index.php?mid=122&fid=13&pl=20 | ||||
| ||||
>А может причина в том, что Signal-Com мешает работе КриптоПро Наврятли так как в данный момент CSP Signal-Com полностью удален. | ||||
| ||||
И все-таки не получается корректно подключить библиотеку (cpcsp.dll) Крипто-Про 3-ьей версии. Точнее при вызове функции CPAcquireContext Windows (XP SP2) возвращает ошибку "Ошибка 2148073501: Библиотека поставщика проинициализирована неправильно." Крипто-Про 3 единственный установленный крипто-провайдер. Кстати я вот чего не понял: в ветке реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider указанно 2 CSP: Crypto-Pro GOST R 34.10-94 Cryptographic Service Provider и Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider у которых указанны имена dll файлов в которых содержаться CP функции. Дак вот, когда установленн Крипто-Про 2-ой версии для этих 2-х CSP dll разные (cpcsp.dll и cpcspe.dll соответственно), а когда установлен Крипто-Про 3-ьей версии dll одинаковые (cpcsp.dll). Т.е. для получения хендла того или иного провайдера мне необходимо в структуре PVTableProvStruc pVTable менять значение полей pVTable.pszProvName pVTable.dwProvType на соответствеющие и подключать только эту библиотеку? | ||||
| ||||
да | ||||
| ||||
а по поводу вызова функций из dll КриптоПро 3-ьей версии? | ||||
| ||||
Посмотрите пример Without в архиве http://www.cryptopro.ru/cryptopro/download/60763684-1BBD-4A65-B475-A2D86A7CDD24/30/3293/sdk.zip | ||||