06.06.2006 7:56:37Импорт открытого ключа Ответов: 22
Дмитрий
Здравствуйте.
Из сертификата открытого ключа выделяю открытый ключ. В каком именно виде он передается в функцию CPImportKey(...), а также что такое "magic", который как я знаю добавляется в импортируемый открытый ключ.
Заранее благодарю.
 
Ответы:
06.06.2006 12:20:58Василий
Не совсем понятно, зачем импортировать ф-ей CPImportKey ключ, полученный из сертификата.
Если есть сертификат, то ф-ей CryptImportPublicKeyInfoEx или CryptImportPublicKeyInfo сразу получаем хендл открытого ключа, который можно использовать в функциях CryptoAPI.
06.06.2006 12:56:27Дмитрий
Не спорю можно и функциями CryptImportPublicKeyInfoEx() и CryptImportPublicKeyInfo(), однако эти функции высокого уровня, а мне необходимо реализовать проверку ЭЦП низкоуровневыми функциями, что требует самостоятельного приведения открытого ключа к тому виду, в котором он передается в функции криптопровайдера.
11.06.2006 11:52:55Дмитрий
Извините за назойливость, но все- таки можно узнать ответы на предыдущие вопросы?
13.06.2006 12:56:42Василий
Можно уточнить, всё-таки, почему нужны низкоуровневые функции?
13.06.2006 17:36:56Дмитрий
Использование низкоуровневых функций необходимо для возможности одновременного использования трех криптопровайдеров /а именно КриптоПро, Сигнал-Ком и VipNet/ на одном компьютере. А так как функции CryptoApi обращаются к криптопровайдеру, который был установлен последним, то использование высокоуровневых функций неприемлемо. Ранее данная проблема обсуждалась на Вашем форуме, но в этих топиках я ничего полезного не подчерпнул.
14.06.2006 10:36:21Василий
Можно прокомментировать:
> А так как функции CryptoApi обращаются к криптопровайдеру, который был установлен последним...

Укажите, пожалуйста, пример последовательности вызовов высокоуровневых функций CryptoAPI (названия функций и параметры), которые неправильно работают при наличии нескольких CSP. А также исходные данные - сертификат читается из хранилища (в этом случае - есть ли ссылка на секретный ключ), или из файла, или из сообщения; в каком формате сообщение и каким ПО подписанное сообщение было получено.
14.06.2006 14:16:23Дмитрий
Здравствуйте Василий.
Итак по порядку:
Сертификат выделяется из сообщения формата PKCS#7. Сообщение подписывается 3 раза разичными CSP
(КриптоПро, Сигнал-Ком и VipNet). И соответственно при попытке проверить подпись созданную CSP Крипто-Про при установленном последним /к примеру/ CSP Signal-Com, происходит ошибка верификации подписи, и наоборот.
Примеры использования высокоуровнеевых функций взяты из MSDN, единственное что в них было измененно, так это значения входных параметров, на значения соответсвующие российским CSP.
14.06.2006 16:11:41Василий
Раз Вы не хотите указать названия вызываемых функций и их параметры - я вряд ли Вам помогу.
15.06.2006 9:58:58Дмитрий
Здравствуйте.
Почему же не хочу, я просто не вижу в этом смысла, но если Вам это так необходимо, то привожу в качестве примера кусок кода, который не работает при нескольких установленных 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);
15.06.2006 11:11:58Дмитрий
Также появилась проблема с использованием библиотек Крипто-Про версии 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";
}
15.06.2006 14:47:13maxdm
а что в pVTable?
15.06.2006 15:08:03Дмитрий
Здравствуйте maxdm.
Забыл скопировать назначения параметров в pVTable.

pVTable.Version = 1;
pVTable.FuncVerifyImage = NULL;
pVTable.FuncReturnhWnd = NULL;

остальные элементы структуры я не заполняю.
15.06.2006 16:20:56maxdm
>остальные элементы структуры я не заполняю.
А зря :)
15.06.2006 17:42:58Дмитрий
Я просто посмотрел тестовые утилитки Крипто-Про, где они заполняют те же параметры что я указал выше, поэтому я решил что этого достаточно.
Если нет, то можите указать примерные значения остальных параметров данной структуры.
16.06.2006 12:36:37maxdm
Нужно имя и тип провайдера указывать, и версию 3.
typedef struct VTableProvStruc { DWORD Version; FARPROC FuncVerifyImage; FARPROC FuncReturnhWnd; DWORD dwProvType; BYTE* pbContextInfo; DWORD cbContextInfo; LPSTR pszProvName;
} VTableProvStruc, *PVTableProvStruc;
А не проще использовать CryptAcquireContext?
16.06.2006 13:21:54Дмитрий
Здравствуйте maxdm.
Спасибо за консультацию по параметрам структуры PVTableProvStruc, однако это не помогло.
Возникает та же ошибка. Возможно есть еще какая - либо причина?
16.06.2006 14:08:40Юрий Маслов
А может причина в том, что Signal-Com мешает работе КриптоПро? Более подробно об этом можно прочитать тут http://www.signal-com.ru/ru/forum/index.php?mid=122&fid=13&pl=20
16.06.2006 15:31:40Дмитрий
>А может причина в том, что Signal-Com мешает работе КриптоПро

Наврятли так как в данный момент CSP Signal-Com полностью удален.
21.06.2006 13:18:12Дмитрий
И все-таки не получается корректно подключить библиотеку (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

на соответствеющие и подключать только эту библиотеку?
21.06.2006 13:36:17maxdm
да
21.06.2006 13:54:36Дмитрий
а по поводу вызова функций из dll КриптоПро 3-ьей версии?
21.06.2006 15:46:47Василий
Посмотрите пример Without в архиве http://www.cryptopro.ru/cryptopro/download/60763684-1BBD-4A65-B475-A2D86A7CDD24/30/3293/sdk.zip