20.06.2006 12:39:07Алгоритм хеширования сообщения. Ответов: 38
Дмитрий
Здравствуйте.
Не подскажите возможно ли каким-либо образом получить алгоритм хеширования из подписанного сообщения\файла в формате PKCS#7?

И еще, существует алгоритм хеширования описываемый в ГОСТ Р 34.11-94, по которому формируется хеш длинной в 512 бит.
Заранее благодарю.
 
Ответы:
20.06.2006 13:59:59Kirill Sobolev
Конечно можно. CryptMsgGetParam(.., CMSG_HASH_ALGORITHM_PARAM, ...).
Хэш по ГОСТ Р 34.11-94 всегда имеет длину 256 бит.
20.06.2006 15:09:50Дмитрий
>CryptMsgGetParam(.., CMSG_HASH_ALGORITHM_PARAM, ...).
в эту функцию передается хендл сообщения, то есть эта функция находит значение алгоритма по какому-то идентификатору (или OID), прав я или нет, и если да то не могли бы Вы подсказать этот идентификатор.
Спасибо.
20.06.2006 15:34:01Kirill Sobolev
Местонахождение информации об алгоритме подписи определяется структурой сообщения PKCS7, а не идентификатором.
20.06.2006 17:16:30Дмитрий
А не подскажите в каком RFC это можно посмотреть (вроде бы в RFC2630, но точно не поню).
И каким образом по структуре файла PKCS#7 можно распознать алгоритм?
20.06.2006 18:22:25Kirill Sobolev
Да, 2630.
Я не сказал что алгоритм хэширования определяется структурой PKCS7. Я имел ввиду, что место расположения информации об алгоритме определяется не идентификатором, а структурой PKCS7. Но сам алгоритм конечно определяется идентификатором, который находится в сообщении.
21.06.2006 12:21:12Дмитрий
>сам алгоритм конечно определяется идентификатором, который находится в сообщении.

а какой идентификатор используется в Крипто-Про?
21.06.2006 13:52:32Kirill Sobolev
#define szOID_CP_GOST_R3411 "1.2.643.2.2.9"
21.06.2006 13:57:56Дмитрий
это для обоих гостов? Если нет, то можно еще уточнить для госта Р 34.10-2001.
21.06.2006 15:06:54Kirill Sobolev
Да, для обоих. При подписи по 94 и 2001 используется одинаковый алгоритм хэширования.
22.06.2006 12:04:41Дмитрий
Здравствуйте Кирилл.
Вы писали:
>Хэш по ГОСТ Р 34.11-94 всегда имеет длину 256 бит
а длинна открытых ключей ГОСТ Р 34.11-94 так же всегда 256 бит?
22.06.2006 17:18:01Kirill Sobolev
ГОСТ Р 34.11-94 - описывает алгоритм хэширования.
Вы наверное имели ввиду ГОСТ Р 34.10-94 - там длина ОК 1024 бит.
23.06.2006 9:27:43Дмитрий
Да Вы правы я имел ввиду ГОСТ Р 34.10-94.
Можно уточнить следующий момент:
Вы мне назвали идентификатор алгоритма хеширования (1.2.643.2.2.9).
Когда я просматриваю подписанный файл через программу dumpASN1, то вижу следующее

0 30 5217: SEQUENCE {
4 06 9: OBJECT IDENTIFIER '1 2 840 113549 1 7 2'
15 A0 5202: [0] {
19 30 5198: SEQUENCE {
23 02 1: INTEGER 1
26 31 12: SET {
28 30 10: SEQUENCE {
30 06 6: OBJECT IDENTIFIER '1 2 643 2 2 9'
38 05 0: NULL
: }
: }
40 30 4044: SEQUENCE {
44 06 9: OBJECT IDENTIFIER '1 2 840 113549 1 7 1'
55 A0 4029: [0] {
59 04 4025: OCTET STRING
: '================================================'
: '================================.. MICROSOFT '
: 'FOUNDATION CLASS LIBRARY : Shifr Project Overvie'

.........../середину пропускаю/

5131 30 10: SEQUENCE {
5133 06 6: OBJECT IDENTIFIER '1 2 643 2 2 9'
5141 05 0: NULL
: }
5143 30 10: SEQUENCE {
5145 06 6: OBJECT IDENTIFIER '1 2 643 2 2 19'
5153 05 0: NULL
: }
5155 04 64: OCTET STRING
: 5E 10 01 81 A5 D1 A8 D5 99 8A 2D 3A 05 8C FA 81
: 76 77 66 1E 7C AC B4 25 08 32 2C 9D 5E 93 D6 9F
: 1C 53 3C F6 56 04 D4 82 30 DB B4 C2 1A C1 66 F9
: 02 75 EE CA DE D8 7D 20 EB 60 D8 C3 A3 2B 23 1C
: }
: }
: }
: }
: }

Данный идентификатор встречается 2 раза и в обоих случаях идентифицируемое значение - NULL.
Возможно я Вас не так понял?
23.06.2006 10:02:38Kirill Sobolev
Не так поняли.
Само наличие этого идентификатора в сообщении говорит о том, что использовался алгоритм ГОСТ Р 34.11-94.
Значение NULL присутствует т.к. у него нет параметров.
В PKCS7 1м случае это информация о собственно алгоритме хеширования, а во 2м - об алгоритме подписи (комбинация ГОСТ Р 34.11-94 и ГОСТ Р 34.10-2001)
23.06.2006 11:36:58Дмитрий
Хм.
>комбинация ГОСТ Р 34.11-94 и ГОСТ Р 34.10-2001.
А каким образом эти два госта комбинируются?
Потому что мне не совсем понятно, если успользуется алгоритм ГОСТа Р 34.11-94 длинна хеша, как вы писали "всегда 256 бит", а как видно выше длинна уже существующего хеша = 512 бит.
23.06.2006 14:16:59Kirill Sobolev
Как они комбинируются собственно в ГОСТ Р 34.10-2001 и описано.
То что выше - это уже преобразованный хэш, у него длина равна длине ОК.
23.06.2006 15:44:34Дмитрий
То есть если я Вас правильно понял, то в функцию CryptVerifySignature() или CPVerifySignature, можно передавать хеш из файла, не смотря на то что размеры у вновь расчитанного хеша не совпадают? Или же хеш из файла подлежит какой-либо обработке перед передачей в данные функции?

Не могли бы Вы указать ссылку гле можно найти описание ГОСТ Р 34.10-2001 и по возможности ГОСТ Р 34.10-94.
Заранее благодарю.
23.06.2006 16:41:04Kirill Sobolev
Конечно можно, если Вы не используете PKCS7, никакой обработки не надо.
Про замечание насчет размеров не понял.
Вот здесь есть описание http://www.password-crackers.com/crypto.html
26.06.2006 12:50:12Дмитрий
За ссылку спасибо (только по видимуму у них какие-то проблемы, ни одна ссылка не работает).
Про размеры хешов: насколько я понял, хеш который я приводил выше по OID'ам Гост Р 34.11-94, и его длинна 32 байта, и к нему еще добавляется еще какая-то инфа и после этого его длинна изменяется до 64 байт, правильно?
И если я использую функцию CPVerifySignature, то мне нужно выделить только хеш, без добавочной информации.
26.06.2006 14:11:58Kirill Sobolev
Отправил Вам то, что когда-то оттуда скачал.
Не к хэшу добавляется какая-то инфа, а хэш преобразуется по алгоритму ГОСТ Р 34.11-94 с помощью секретного ключа подписчика.
26.06.2006 15:05:20Дмитрий
Спасибо.
У меня вот еще такой вопрос:
если функция CPImportKey возвращает значение true, то я могу быть уверен что блоб открытого ключа /который передается в функцию как входной параметр/ правилен, если я его "собираю" его вручную.
26.06.2006 15:36:12Kirill Sobolev
Если имеется ввиду функция, реализованная в КриптоПро СSP, то да, можете.
27.06.2006 11:56:47Дмитрий
Здравствуйте.
>хэш преобразуется по алгоритму ГОСТ Р 34.11-94 с помощью секретного ключа подписчика.

Обратная операция производится через открытый ключ подписчика, и при вызове функции CPVerifySignature выполняется автоматически?
И еще вопрос: в функцию
CPVerifySignature(
HCRYPTPROV hProv,
HCRYPTHASH hHash,
const BYTE* pbSignature,
DWORD dwSigLen,
HCRYPTKEY hPubKey,
LPCWSTR sDescription,
DWORD dwFlags
)
в качестве входного параметра pbSignature передается значение хеша или же подпись целеком?
28.06.2006 11:04:58Kirill Sobolev
Да.
Подпись целиком.
28.06.2006 16:44:45Дмитрий
То есть входной параметр функции верификации, указанный выше, составляется из последовательного "скрепления" байтов,которые добавляются в исходный файл в том же порядке в котором они встречаются в файле?
28.06.2006 17:01:50Kirill Sobolev
Не понял Вашего вопроса.
В том примере, который Вы привели, pbSignature будет указатель на буфер
: 5E 10 01 81 A5 D1 A8 D5 99 8A 2D 3A 05 8C FA 81
: 76 77 66 1E 7C AC B4 25 08 32 2C 9D 5E 93 D6 9F
: 1C 53 3C F6 56 04 D4 82 30 DB B4 C2 1A C1 66 F9
: 02 75 EE CA DE D8 7D 20 EB 60 D8 C3 A3 2B 23 1C
hHash - дескриптор объекта, в котором содержится хэш от исходного документа
28.06.2006 17:26:50Дмитрий
Ну в принципе это я и хотел увидеть. Спасибо.
11.07.2006 15:45:13Дмитрий
Здравствуйте.
Ранее в этом топике я задавал Вам вопрос на счет функции CPImportKey (...возвращает значение true, то ...), для всех остальных функций реализованных в КриптоПро СSP, я так же могу быть уверенным что значения входных и выходных параметров корректны.

И еще вопрос: Когда создается хеш функцией CPCreateHash() в качестве алгоритма передается алгоритм хеширования, а не подписи? /И именно для примера указанного выше он должен быть равным 32978/
11.07.2006 16:47:05Kirill Sobolev
Да, в функцию создания хэша передается именно алгоритм хэширования :)
11.07.2006 17:15:47Дмитрий
Тогда подскажите, что я не так делаю:
1) Получаю контекст провайдера:
pVTable.Version = 3;
pVTable.FuncVerifyImage = NULL;
pVTable.FuncReturnhWnd = NULL;
pVTable.pszProvName = "Crypto-Pro GOST R 34.10-94 Сryptographic Service Provider";
pVTable.dwProvType = 71;
pVTable.cbContextInfo = 0;
pVTable.pbContextInfo = NULL;
CPAcquireContext(&Prov, NULL, CRYPT_VERIFYCONTEXT, &pVTable);

2) Импортирую ключ (CPImportKey возвращает true, а так как Вы писали что в этом случае ключ правилен, то на этом шаге код не привожу)

3) Нахожу алгоритм хеша по OID, переводя значение OID в значение алгоритма.
hashAlg = CertOIDToAlgId((LPCSTR)data);
[in] data = 1.2.643.2.2.9
[out] hashAlg = 32798

4) Создаю хеш
CPCreateHash(Prov,hashAlg,0,0,&hHash);

5) Из ранее полученных данных (их получение пропускаю) расчитываю хеш данных
CPHashData(Prov,hHash,signFile.captionOfFile,signFile.sizeOfcaptionFile,0);
Размер хеш последовательности 32 байта

6) Получаю подпись из подписанного файла (размер 64 байта)

7) И все это передаю в функцию
CPVerifySignature(Prov,hHash,signFile.hash,signFile.hashSize,ImportedKey,NULL,0);

Все CP функции, кроме последней возвращают true.
Подпись создана функциями с префиксом Crypt, и функциями с этим же префиксом верифицируется.
11.07.2006 17:50:48Kirill Sobolev
Судя по размеру подписи она у Вас на 2001 ГОСТе, при этом Вы используете "Crypto-Pro GOST R 34.10-94 Сryptographic Service Provider".
11.07.2006 18:30:04Дмитрий
Попробовал, не работает.
Вот что поменял: подгрузил другую библиотеку (так как я на данный момент пользуюсь КриптоПро CSP 2 версии) с cpcsp.dll на cpcspe.dll и изменил некоторые поля структуры pvTable

pVTable.pszProvName = "Crypto-Pro GOST R 34.10-2001 Сryptographic Service Provider";
pVTable.dwProvType = 75;

Вроде больше ничего менять не надо для того чтобы подгрузить КриптоПро Гост Р 34.10-2001.
12.07.2006 12:01:18Kirill Sobolev
А что GetLastError говорит?
12.07.2006 12:31:30Дмитрий
На счет подписи.
1) Подписью, на сколько я понял, является хеш, преобразованный на закрытом ключе подписчика?
2) Не совсем ясно как Вы определили ГОСТ по размеру подписи?
12.07.2006 12:38:11Дмитрий
>А что GetLastError говорит?
он говорит "Код ошибки - 2148073478: Неправильная подпись."
12.07.2006 12:40:44Kirill Sobolev
1)да
2)94 - 1024 бита, 2001 - 512 бит
12.07.2006 13:22:14Дмитрий
1) Как видно из ветки реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo значения алгоритмов хеширования для Crypto-Pro GOST R 34.10-94\2001 CSP одинаковые и равны 32798, это так и есть?
2) Нормально что хеш вычисленный Crypto-Pro GOST R 34.10-2001 CSP = хешу вычисленному Crypto-Pro GOST R 34.10-94? CSP
12.07.2006 13:48:30Kirill Sobolev
Да, и там и там используется ГОСТ Р 34.11-94.
31.07.2006 9:05:24Дмитрий
>...если Вы не используете PKCS7, никакой обработки не надо.
Подскажите пожалуйста каким образом обрабатывается подпись полученная из файла PKCS#7, перед передачей в функцию верификации?