| ||||
| ||||
Не получается сделать импорт блоба открытого ключа получателя на своей ключевой паре. Делаю так: hFile1 = ::CreateFile ("c:\\BLOB.key", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (!hFile1) { Form1->Memo1->Lines->Add("Pub key file IO error"); return false; } DWORD dwSize = ::GetFileSize (hFile1, NULL); ::ReadFile (hFile1, szPubKey, dwSize, &dwPubKeySize, NULL); ::CloseHandle (hFile1); if (dwSize != dwPubKeySize) { Form1->Memo1->Lines->Add("Pub key file read error"); return false; } // 1) Initialize CryptoAPI bRes = CryptAcquireContext (&hCryptProv, NULL, NULL, DEF_PROV, 0); if (bRes) Form1->Memo1->Lines->Add("CryptAcquireContext () ... OK"); else Form1->Memo1->Lines->Add("Can't initialize CryptoAPI"); // Get User key if (!CryptGetUserKey(hCryptProv, AT_KEYEXCHANGE, &hUserKey)) Form1->Memo1->Lines->Add("Can't get user key"); else Form1->Memo1->Lines->Add("CryptGetUserKey success"); // 2) Create session key //CryptGenKey (ïðîâàéäåð, àëãîðèòì, ôëàãè, êëþ÷) bRes = CryptGenKey(hCryptProv, CALG_G28147, CRYPT_EXPORTABLE, &hSesKey); if (bRes) Form1->Memo1->Lines->Add("CryptGenKey (session) ... OK"); else Form1->Memo1->Lines->Add("CryptGenKey (session) error"); // 3) Import public key bRes = CryptImportKey (hCryptProv, (BYTE *)&szPubKey[0], dwPubKeySize, hUserKey, 0, &hPPKey); if (bRes) Form1->Memo1->Lines->Add("CryptImportKey (public) ... OK"); else {Form1->Memo1->Lines->Add("CryptImportKey (public) error"); GetLastError(); return false;} На импорте выходит ошибка. В чем может быть проблема? Делаю все по примерам на этом форуме... | ||||
Ответы: | ||||
| ||||
Какая ошибка? | ||||
| ||||
GetLastError() возвращает 5 (не знаю к сожалению как посмотреть по предопределенным значениям). | ||||
| ||||
хм. странная последовательность вызовов - что сделать то пытаетесь? | ||||
| ||||
Я пытаюсь зашифровать данные. Сначала создаю сессионный ключ и затем импортирую открытый ключ получателся на своей ключевой паре для получения ключа парной связи. Если что-то делаю не так - поправьте пожалуйста. | ||||
| ||||
Можно уточнить значения: 1) DEF_PROV 2) dwPubKeySize (после чтения файла) 3) алгоритмы ключей AT_KEYEXCHANGE - отправителя и получателя | ||||
| ||||
1) #define DEF_PROV 75 2) dwPubKeySize = 164 байта 3) это задается в сертификате открытого ключа? если да, то алгоритмы ГОСТ Р 34.10-94 | ||||
| ||||
В сертификате - про открытый ключ. А в Вашем контейнере, судя по всему, алгоритм ключа (AT_KEYEXCHANGE) ГОСТ... 2001. Если Вы создавали контейнер на CSP 75-го типа и не указали конкретный алгоритм при создании ключа AT_KEYEXCHANGE - то он будет 2001-го ГОСТа. Импорт открытого ключа для создания ключа Диффи-Хеллмана возможен только при совпадении алгоритмов (открытого ключа и своего ключа AT_KEYEXCHANGE) - либо оба ГОСТ 94, либо оба 2001. | ||||
| ||||
Спасибо за разъяснение! Я в этом форуме в одной из веток читал, что если БЛОБ 164 байта, то это 94 год, а если 100 байт - 01 год. Открытый ключ таким образом у меня 94 года, а как мне указать AT_KEYEXCHANGE 94 года? через установку параметров ключа? | ||||
| ||||
Лучше сделайте новый ключевой контейнер на CSP не 75-го, а 71-го типа. И в нём ключ AT_KEYEXCHANGE. Кстати, по информации из ЦБС ФСБ: ГОСТ Р 34.10-94 разрешается использовать для подписи только до 31 декабря 2007 года. Далее только для проверки подписи. Есть мнение, что и для согласования ключей ГОСТ 94-го года скоро будет запрещён (точная дата пока не определена) или, во всяком случае, будет ограничен гарантированыый срок сохранения в тайне информации при применении для согласования ключей ГОСТа 94-го года. | ||||
| ||||
Как можно указать тип CSP для ключевого контейнера? Когда я делаю "Установить личный сертификат" там явно не выбирается CSP. Или это не интерактивно, а программно устанавливается? | ||||
| ||||
В Вашем сообщении от 28.04.2007 16:41:43 есть вызов CryptAcquireContext (&hCryptProv, NULL, NULL, DEF_PROV, 0); т.е. открыть существующий контейнер с именем по умолчанию на криптопровайдере (CSP) 75-го типа. Раз контейнер существующий, значит, кто-то его создал. Это можно было сделать программно (CryptAcquireContext с флажком CRYPT_NEWKEYSET) или при создании запроса на сертификат. Во время создания и выбирался алгоритм ключа AT_KEYEXCHANGE (ГОСТ 94 или 2001). Изменить алгоритм ключа после создания нельзя. Можно только сделать новый ключ. | ||||
| ||||
Прошу прощение за возможное дилетанство, но я создал контейнер не программно и не через запрос на сертификат. У меня была дискета с закрытым ключом и файл *.cer с сертификатом открытого ключа. Я зашел в настройки криптопровайдера, сделал "установить личный сертификат" и у меня появился контейнер. Получается, по умолчанию у меня AT_KEYEXCHANGE получился 2001 года. При таком способе установки можно что-то исправить. Может алгоритм AT_KEYEXCHANGE задается в сертификате открытого ключа? | ||||
| ||||
Ещё раз повторю - алгоритм ключа задаётся при создании ключевого контейнера, поменять его нельзя. Если в Вашем контейнере ключ ГОСТ 2001, а в чужом блобе открытого ключа - 94, то создать ключ парной связи (Диффи-Хеллмана) невозможно. Однако, если бы у Вас был сертификат получателя (а не блоб открытого ключа), то можно организовать процедуру шифрования при использовании более высокоуровневых функций CryptoAPI, например, CryptEncryptMessage | ||||