Статус: Новичок
Группы: Участники
Зарегистрирован: 29.07.2014(UTC) Сообщений: 2 Откуда: Санкт-Петербург Сказал(а) «Спасибо»: 1 раз
|
Дано:- Debian 7.4 wheezy
- КриптоПро CSP 3.6.1
Задачи:
- Посчитать HMAC на основе известного ключа (в сыром виде) для алгоритма MD5
- Посчитать HMAC на основе известного ключа (в сыром виде) для алгоритма SHA1
- Импортировать сырой симметричный ключ ГОСТ 28147-89 для дальнейшего использования
- Посчитать имитовставку ГОСТ 28147-89, сырой симметричный ключ также прилагается
ПодходВсе вышеперечисленные задачи требуют наличия актуального ключа шифрования в понятиях HCRYPTKEY CryptoAPI/CAPILite. В нашем случае, во всех задачах ключ приходит извне в сыром виде, поэтому CryptDeriveKey() и CryptGenKey() неприменимы. Применим, теоретически, CryptImportKey(), описание которого на MSDN (1) содержит отличную ссылку на пример импорта ключа из PLAINTEXTKEYBLOB (2). При этом, для первых двух задач тот же MSDN рекомендует использовать ключ типа CALG_RC2, а при использовании ключей более 16 байт необходимо также использование флага CRYPT_IPSEC_HMAC_KEY (о нём немного ниже). Практически, код для подобного импорта, c учётом случайных интернетных ссылок (3), выглядит так: Код:
typedef struct _capi_blob{
BLOBHEADER header;
DWORD len;
BYTE key[];
} capi_blob;
...
void hmac_init(... uint8_t *key, int key_len ...)
capi_blob *blb;
DWORD bsize;
...
bsize = key_len + sizeof(*blb);
blb = calloc(1, bsize); // who cares about NULL?
blb->header.bType = PLAINTEXTKEYBLOB;
blb->header.bVersion = CUR_BLOB_VERSION;
blb->header.aiKeyAlg = CALG_RC2;
memcpy(blb->key, key, key_len);
blb->len = key_len;
if (!CryptImportKey(cryptoprov, (BYTE *) blb, bsize,
0, CRYPT_EXPORTABLE, &ctx->c))
msg("Failed CryptImportKey (0x%x), bsize: 0x%x, key_len: %d", GetLastError(), bsize, key_len);
При этом, cryptoprov может быть получен так: Код:
...
if (!CryptAcquireContext(
&cryptoprov,
0,
NULL,
PROV_GOST_2001_DH,
CRYPT_VERIFYCONTEXT))
...
А может быть так: Код:
...
if (!CryptAcquireContext(cprov, "TestContainer", MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_NEWKEYSET))
...
Что имеет своё влияние на результат, но об этом ниже. ПроблемаПри использовании указанного выше подхода для самой первой задачи имеем с провайдером PROV_GOST_2001_DH: Код:Failed CryptImportKey (0x80090005), bsize: 0x24, key_len: 24
При использовании PROV_RSA_FULL: Код:Failed CryptImportKey (0x57), bsize: 0x24, key_len: 24
Очевидно, что ни NTE_BAD_DATA, ни ERROR_INVALID_PARAMETER не являются корректными ответами на поставленную задачу. В связи с чем были проведёны дополнительные исследования вопроса. Дополнительне подходыВо-первых, было подозрение на размер ключа и связь с CRYPT_IPSEC_HMAC_KEY, но, увы, как показало ручное обрезание ключа до 16, 8 и 5 байт, результат не меняется. Во-вторых, коль скоро наш ключ на входе имеет длину в 24 байта или 192 бита, была произведена замена CALG_RC2 на CALG_3DES, результат не изменился. В-третьих, был опробован существенно более сложный путь импорта через PRIVATEKEYBLOB (4), код этого варианта на 95% соответствует четвёртой ссылке, но и он результата не дал, ошибки те же. В-четвёртых, так как, теоретически, реализации разных RC2/RC4/3DES и прочей ереси в библиотеках "КриптоПро" может и не быть (хотя в заголовках-то всё есть), был опробован импорт CALG_G28147 с размером ключа в 32 байта как по схеме PLAINTEXTKEYBLOB, так и по схеме PRIVATEKEYBLOB, что уже имеет прямое отношение к третьей и четвёртой задачам. Результат стабильный и неизменный --- те же ошибки, с поправкой на криптопровайдера. Вопросы1) Как же нам посчитать HMAC, может есть другие методы? 2) Как заимпортировать сырой ключ ГОСТ 28147-89? 3) Что случилось с CRYPT_IPSEC_HMAC_KEY? Ссылки1) http://msdn.microsoft.co...p/aa380207(v=vs.85).aspx2) http://msdn.microsoft.co...p/aa382383(v=vs.85).aspx3) http://masm32.com/board/index.php?topic=1612.04) http://www.phdcc.com/cryptorc4.htm
|