27.09.2005 8:07:26An internal error occurred. Ответов: 6
Евгений
Поиском пользовался. Много всего прочитал. В файле export.c был. Помогите разобраться с проблемой.
Код:
Result = CryptAcquireContext(&csp, NULL, CP_DEF_PROV, PROV_GOST_DH, CRYPT_VERIFYCONTEXT);

buffer = (BYTE*)malloc(64);
Result = CryptGenRandom(csp, 64, buffer);
...
//Сохраняю полученные рэндомные данные в свою базу данных для дальнейшего использования.
...
Result = CryptCreateHash(csp, CertOIDToAlgId(szOID_CP_GOST_R3411), NULL, 0, &hash);

Result = CryptHashData(hash, buffer, 64, 0);

Result = CryptDeriveKey(csp, CALG_G28147, hash, 0, &key1);
...
//Сохораняю вектор инициализации в свою базу данных для дальнейшего использования.
...
buffer = (BYTE*)"Data for encrypting.";

leng = strlen((char*)buffer); len = 0;
Result = CryptEncrypt(key1, 0, TRUE, 0, buffer, &len, leng);

В результате на функции CryptEncrypt получаю ошибку, что стоит в заглавии данного вопроса.
Помогите разобраться. Просьба во избежании дальнейшних распросов по этой теме ответы в краткой форме "Неправильное назначение ключа" заменять более длинными ответами. Заранее благодарен вниманию и помощи.
 
Ответы:
27.09.2005 16:42:58Василий
А точно результат CertOIDToAlgId(szOID_CP_GOST_R3411) равен CALG_GR3411 ?
27.09.2005 16:52:52Евгений
Василий, да. После написания данного сообщения перечитал его и в коде своем поправил на CALG_GR3411. Та же самая проблема.
27.09.2005 18:53:02Василий
ок, тогда пришлите полный исходник примера, приводящего к ошибке.

Вы используете CSP версии 2.0? Какой билд?
27.09.2005 19:42:31Евгений
ОС - Windows XP SP2. СКЗИ КриптоПРО 2.0 билд 2083.

Василий. Проблему я решил. Но чужое мнение еще требуется.
Суть в следующем -
Был код именно на шифрование:

buffer = (BYTE*)"Data for encrypting.";
len = leng = strlen((char*)buffer);

Result = CryptEncrypt(key1, 0, TRUE, 0, buffer, &len, leng);

Ошибка в этом кусочке и стала причиной этого вопроса.

Изменил:

const char* str = "Data for encrypting.";
len = strlen(str);
leng = 64;

buffer = (BYTE*)malloc(leng);
memset(buffer, 0, leng);
memcpy(buffer, str, len);

Result = CryptEncrypt(key1, 0, TRUE, 0, buffer, &len, leng);

Все нормально зашифровалось. При этом длина исходного текста - 20 байт. Длина шифртекста - 20 байт. Вопрос - почему в первом случае происходит ошибка?
И еще - как быть с данными неизвестной длины, какого размера выделять буфер под шифртекст?
Неужели немного большее число кратное размеру блока?
А почему тогда размеры открытого и шифр-текста совпадают?
Поясните, пожалуйста.
28.09.2005 10:13:42Юрий
А что применение функций вида:
CryptEncrypt(key1, 0, TRUE, 0, NULL, &len, leng)
Вам неизвестно?
В этом случае в len возвращает длину буфера, который требуется под шифротекст. Точно также действуют все функции CryptoAPI, которые работают с данными неизвестной длины.
28.09.2005 10:34:45Василий
Евгению.
По умолчанию в качесве режима шифрования используется режим гаммирования, поэтому длина шифртекста равна длине открытого текста. В режиме блочного шифрования (если его задать), действительно, длина шифртекста больше (выровнена по размеру блока, т.е. 8 байт), а в случае, если длина открытого текста уже кратна размеру блока, то добавляется ещё один блок.

Но! Всё это не повод для ошибки 0x80090020 = NTE_FAIL, т.к., если размер буфера недостаточен, функция возвращает нужную длину и устанавливает ошибку ERROR_MORE_DATA.

По-видимому, тут дело в коде (выделение памяти под буфер).
Попробуйте так:

const char* str = "Data for encrypting.";
len = leng = strlen(str);

buffer = (BYTE*)malloc(leng);
memcpy(buffer, str, len);

Result = CryptEncrypt(key1, 0, TRUE, 0, buffer, &len, leng);