02.10.2003 14:37:24CryptGetKeyParam(..., KP_BLOCKLEN, ...) возвращает 0x2000 для 256-битного ключа CALG_G28147 Ответов: 4
Maxim Egorushkin
В документации MSDN и КриптоПро сказано, что для сессионного ключа CryptGetKeyParam() с флагом KP_BLOCKLEN должен вернуть размер ключа/блока в битах. Для MS провайдеров это действительно так.

Почему для 256 битного ключа CALG_G28147 мне возвращается значение 0x2000? Что это значит?

Вот код:

void f()
{
HCRYPTPROV prv;
::CryptAcquireContext(&prv, 0, CP_DEF_PROV, PROV_GOST_DH, CRYPT_VERIFYCONTEXT);
HCRYPTKEY key;
::CryptGenKey(prv, CALG_G28147, 0, &key);
DWORD key_size, key_size_size(sizeof(key_size));
::CryptGetKeyParam(key, KP_BLOCKLEN, (BYTE*)&key_size, &key_size_size, 0);
// key_size == 0x2000
}
 
Ответы:
06.10.2003 14:23:52Василий
По умолчанию при создании ключа ГОСТ 28147-89 режим алгоритма шифрования
CRYPT_MODE_CFB - режим гаммирования с обратной связью.
Размер "блока" в этом случае возвращается условно равным рекомендуемой (с точки зрения производительности) величине фрагмента шифруемого текста, который будет обработан за один вызов CryptEncryptMessage.
06.10.2003 14:35:28Maxim Egorushkin
Простите, я забыл упомянуть, что режим у меня CRYPT_MODE_CBC:

void f()
{
HCRYPTPROV prv;
::CryptAcquireContext(&prv, 0, CP_DEF_PROV, PROV_GOST_DH, CRYPT_VERIFYCONTEXT);
HCRYPTKEY key;
::CryptGenKey(prv, CALG_G28147, 0, &key);
DWORD mode(CRYPT_MODE_CBC);
::CryptSetKeyParam(key, KP_MODE, (BYTE*)&mode, 0);
DWORD key_size, key_size_size(sizeof(key_size));
::CryptGetKeyParam(key, KP_BLOCKLEN, (BYTE*)&key_size, &key_size_size, 0);
// key_size == 0x2000
}

Для этого режима также не возвращается реальный размер блока?
06.10.2003 18:04:15Василий
Для блочного алгоритма указанное значение 8192 возвращается потому, что, как было установлено, параметр используется некоторыми функциями CryptoAPI не так, как он описан в MSDN. А именно, полученное значение используется функцией CryptEncryptMessage для определения размера фрагментации текста. Этот факт сильно снижает производительность в случае, когда возвращается истинный размер блока в ГОСТе - 64 бита.
Поэтому было принято решение возвращать оптимальное по скорости выполнения значение. К сожалению, информация об этом факте не отражена в документации на распространяемый сейчас провайдер.
Исправленный вариант документации будет для новых версий, а также будет выложен на нашем сайте для текущей версии.
06.10.2003 18:51:35Maxim Egorushkin
Спасибо.