Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline al  
#1 Оставлено : 26 июня 2015 г. 11:21:54(UTC)
al

Статус: Активный участник

Группы готовые для захвата: Участники
Зарегистрирован: 13.06.2013(UTC)
Сообщений: 83
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 16 раз
Поблагодарили: 1 раз в 1 постах
Есть клиент и сервер.
Клиент - карта, Сервер - программа исользующая КриптоПро CSP.
Карта шифрует данные (длина данных не кратна длине блока) по ГОСТ28147 в режиме CFB (выравнивание не требуется, карта его не делает).
По открытым данным карта вычисляет имитовставку. Предварительно делая выравнивание по такому алгоритму:
Цитата:

static void Align(unsigned char * data, int dsz, unsigned char ** data_aligned, int * asz){
*asz = dsz;
if(dsz <= 8) *asz = 16;
else if(dsz%8) *asz = dsz+(8-dsz%8);
*data_aligned = (unsigned char*)malloc(*asz);
memset(*data_aligned, 0, *asz);
memcpy(*data_aligned, data, dsz);
if(dsz <= 8)
memcpy(*data_aligned+8, data, dsz);
}


Пакет приходит на сервер, где производится расшифрование пакета с проверкой имитовставки в один вызов КриптоПро:
Цитата:

//расшифровать данные и вычислить имиту в одно действие
//в случае успешного выполнения возвращает 1, в случае ошибки - 0
static int DecryptImit(HCRYPTPROV * phProv, HCRYPTKEY * phKey, LPBYTE pbIn, DWORD dwInLen, LPBYTE pbOut, DWORD dwOutLen){
DWORD dwLen, dwMode;
HCRYPTHASH hHash = 0;
BYTE * data = NULL;
dwLen=dwInLen;
data = (BYTE *)malloc(dwLen);
if(!data){
err_msg(__FILE__, __FUNCTION__, __LINE__,NULL);
return 0;
}
memcpy(data,pbIn,dwInLen);//SV плюс зашифрованные данные с имитой по ним
dwMode = CRYPT_MODE_CFB;
if(!CryptSetKeyParam(*phKey, KP_MODE, (BYTE*)&dwMode, 0)){
free(data);
err_msg(__FILE__, __FUNCTION__, __LINE__," (error: 0x%x)\n", GetLastError());
return 0;
}
dwMode = ZERO_PADDING;
if(!CryptSetKeyParam(*phKey, KP_PADDING, (BYTE*)&dwMode, 0)){
free(data);
err_msg(__FILE__, __FUNCTION__, __LINE__," (error: 0x%x)\n", GetLastError());
return 0;
}
if(!CryptCreateHash(*phProv, CALG_G28147_IMIT, *phKey, 0, &hHash)){
free(data);
err_msg(__FILE__, __FUNCTION__, __LINE__," (error: 0x%x)\n", GetLastError());
return 0;
}
if(!CryptDecrypt(*phKey, hHash, TRUE, CP_CHP(CP_CHP_IV_USER|CP_CHP_HASH_ENCRYPT|CP_CHP_HASH_PACKET,0,0,1), data, &dwLen)){
free(data);
err_msg(__FILE__, __FUNCTION__, __LINE__," (error: 0x%x)\n", GetLastError());
return 0;
}
if(hHash)CryptDestroyHash(hHash);
memcpy(pbOut,&data[SEANCE_VECTOR_LEN],dwOutLen); //расшифрованные данные
free(data);
return 1;
}


Вызывается так:
Цитата:

memcpy(pbIn,iv,8);
memcpy(&pbIn[8],data,DATA_LEN);
memcpy(&pbIn[8+DATA_LEN],imit,4);
if(!DecryptImit(&hProvClient, &hSessionKey, pbIn, 8+DATA_LEN+4, pbOut, DATA_LEN))goto end;


Далее сервер формирует ответный пакет клиенту, в котором содержится шифротекст и имита, полученные за один вызов КриптоПро:
Цитата:

//зашифровать данные и вычислить имиту в одно действие
//в случае успешного выполнения возвращает 1, в случае ошибки - 0
static int CryptImit(HCRYPTPROV * phProv, HCRYPTKEY * phKey, LPBYTE pbIn, DWORD dwInLen, LPBYTE pbOut, DWORD dwOutLen){
DWORD dwLen, dwMode;
HCRYPTHASH hHash = 0;
BYTE * data = NULL;
dwLen=dwInLen; //inout буфер: на входе - iv, data, <место под имиту>, на выходе: iv(мусор), шифротекст, имита
data = (BYTE *)malloc(dwLen);
if(!data){
err_msg(__FILE__, __FUNCTION__, __LINE__,NULL);
return 0;
}
memcpy(data,pbIn,dwInLen-EXPORT_IMIT_SIZE); //имиты на входе нет, есть только место под неё
dwMode = CRYPT_MODE_CFB;
if(!CryptSetKeyParam(*phKey, KP_MODE, (BYTE*)&dwMode, 0)){
free(data);
err_msg(__FILE__, __FUNCTION__, __LINE__," (error: 0x%x)\n", GetLastError());
return 0;
}
dwMode = ZERO_PADDING;
if(!CryptSetKeyParam(*phKey, KP_PADDING, (BYTE*)&dwMode, 0)){
free(data);
err_msg(__FILE__, __FUNCTION__, __LINE__," (error: 0x%x)\n", GetLastError());
return 0;
}
if(!CryptCreateHash(*phProv, CALG_G28147_IMIT, *phKey, 0, &hHash)){
free(data);
err_msg(__FILE__, __FUNCTION__, __LINE__," (error: 0x%x)\n", GetLastError());
return 0;
}
if(!CryptEncrypt(*phKey, hHash, TRUE, CP_CHP(CP_CHP_IV_USER|CP_CHP_HASH_ENCRYPT|CP_CHP_HASH_PACKET,0,0,1), data, &dwLen, dwLen)){
free(data);
err_msg(__FILE__, __FUNCTION__, __LINE__," (error: 0x%x)\n", GetLastError());
return 0;
}
if(hHash)CryptDestroyHash(hHash);
memcpy(pbOut,&data[SEANCE_VECTOR_LEN],dwOutLen); //зашифрованные данные и имита по ним
free(data);
return 1;
}


Вызывается так:
Цитата:

memcpy(pbIn,iv,8);
memcpy(&pbIn[8],data,DATA_LEN);
if(!DecryptImit(&hProvClient, &hSessionKey, pbIn, 8+DATA_LEN+4, pbOut, DATA_LEN+4))goto end;


Если в обмене участвуют данные, длина которых кратна длине блока, то все работает.
Если в обмене участвуют данные, длина которых не кратна длине блока, то:
1) если длина данных меньше дины блока (<8 байт), то выдается ошибка NTE_BAD_HASH, 0x80090002,
2) если длина данных больше длины блока, то всё работает.

У нас на клиенте (на карте), при вычислении имитовставки, если данные имеют длину меньше длины блока, то при выравнивании блок дополняется нулями и задваивается.
Правильно ли я понимаю, что:
1) В КриптоПро такого "задваивания" как у нас (в случае если длина данных меньше длины блока) не производится (т.е. результатом выравнивания будет один блок дополненный нулями)?
2) Алгоритм подобный приведенному выше (функция Align) в КриптоПро не поддерживается ?

Отредактировано пользователем 26 июня 2015 г. 12:34:05(UTC)  | Причина: уточнил суть вопроса

Offline al  
#2 Оставлено : 26 июня 2015 г. 12:04:45(UTC)
al

Статус: Активный участник

Группы готовые для захвата: Участники
Зарегистрирован: 13.06.2013(UTC)
Сообщений: 83
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 16 раз
Поблагодарили: 1 раз в 1 постах
Убрал установку ZERO_PADDING в функциях на сервере.
Ситуация не изменилась - на данных длиной не кратной длине блока, но больше одного длока (например, длиной 21 байт)
всё работает. На данных длиной меньше длины блока (например, длиной 6 байт) не работает (NTE_BAD_HASH).
Т.е установка типа выравнивания на ключ "не играет" - данные при вычислении имитовставки, как и раньше, выравниваются нулями до длины блока.
Вопрос тем не менее остается (последние четыре строки предыдущего поста).

Отредактировано пользователем 26 июня 2015 г. 12:05:19(UTC)  | Причина: Не указана

Offline Станислав Смышляев  
#3 Оставлено : 26 июня 2015 г. 13:15:07(UTC)
Станислав Смышляев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 10.04.2013(UTC)
Сообщений: 186
Российская Федерация

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 81 раз в 62 постах
Добрый день!

Удваивания блока у нас не происходит – стандарт это не предполагает.

Поддержки данного механизма (как мне представляется, он у Вас авторский) у нас нет.

Строго говоря, в отношении имиты стандарт является самодостаточным. Но в случае необходимости могу Вам предложить также использовать определенные в стандартах алгоритмы выравнивания данных: PKCS#5, ISO 10126, ANSI X.923.
С уважением,
Станислав Смышляев, к.ф.-м.н.,
Заместитель генерального директора ООО "КРИПТО-ПРО"
Техническую поддержку оказываем здесь.
Наша база знаний.
thanks 1 пользователь поблагодарил Станислав Смышляев за этот пост.
al оставлено 26.06.2015(UTC)
Offline al  
#4 Оставлено : 26 июня 2015 г. 13:49:53(UTC)
al

Статус: Активный участник

Группы готовые для захвата: Участники
Зарегистрирован: 13.06.2013(UTC)
Сообщений: 83
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 16 раз
Поблагодарили: 1 раз в 1 постах
Спасибо за исчерпывающий ответ.
Да, механизм выравнивания на карте - авторский.
Тогда в моем случае у меня лишь два варианта: либо выравнивать данные сразу (до выполнения шифрования/вычисления имиты),
либо - отдельно вызывать шифрование (на невыровненных данных) и отдельно - вычисление имитовставки (с предварительным выравниванием).
Но в последнем случае увеличится количество вызовов КриптоПро. Да, и последний вариант, - сделать на карте алгоритм выравнивания настраиваемым.

Если позволите, дополнительный вопрос.
А каким образом выставить соответствующий тип алгоритма выравнивания, который будет использоваться в функции "шифрования и хеширования пакета" (где операции шифрования и вычисления имитовставки производятся в одном вызове КриптоПро) ?
Как я писал выше, установка "ZERO_PADDING на ключ" не влияет на результат выполнения функции "шифрования и хеширования пакета".
Не влияет также и установка PKCS5_PADDING. Должна же быть возможность для функции "шифрования и хеширования пакета" установить извне тип выравнивания (из тех, что Вы перечислили) ?

PS. Коллеги подсказали, что (скорее всего) основанием для такого решения с "задвоением" выровненных на длину блока данных (когда длина данных меньше блока), послужил п. 5.1. ГОСТ 28147-89.

Отредактировано пользователем 26 июня 2015 г. 16:29:52(UTC)  | Причина: добавил пояснение к авторскому алгоритму

Offline al  
#5 Оставлено : 6 июля 2015 г. 8:22:15(UTC)
al

Статус: Активный участник

Группы готовые для захвата: Участники
Зарегистрирован: 13.06.2013(UTC)
Сообщений: 83
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 16 раз
Поблагодарили: 1 раз в 1 постах
При вычислении имитовставки библиотека КриптоПро выравнивает исходные данные следующим образом:
1) Если длина данных меньше длины блока, данные выравниваются нулями на границу двух блоков.
2) Если длина данных равна длине блока, данные выравниваются нулями на границу двух блоков.
3) Если длина данных больше длины блока, но не кратна длине блока, данные выравниваются нулями на границу блока.
В остальных случаях выравнивание не производится.

Но вопрос в том, можно ли задать алгоритм выравнивания извне для функции "шифрования и хеширования пакета" (где операции шифрования
и вычисления имитовставки производятся внутри одного вызова) ? И если можно, то как это сделать ?
Ибо установка PKCS5_PADDING или ZERO_PADDING на результат выравнивания не влияет.

Отредактировано пользователем 15 июля 2015 г. 11:05:25(UTC)  | Причина: Не указана

Offline al  
#6 Оставлено : 15 июля 2015 г. 11:02:14(UTC)
al

Статус: Активный участник

Группы готовые для захвата: Участники
Зарегистрирован: 13.06.2013(UTC)
Сообщений: 83
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 16 раз
Поблагодарили: 1 раз в 1 постах
Спасибо. Тему можно закрывать.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.