| ||||
| ||||
Здравствуйте. Не подскажите возможно ли каким-либо образом получить алгоритм хеширования из подписанного сообщения\файла в формате PKCS#7? И еще, существует алгоритм хеширования описываемый в ГОСТ Р 34.11-94, по которому формируется хеш длинной в 512 бит. Заранее благодарю. | ||||
Ответы: | ||||
| ||||
Конечно можно. CryptMsgGetParam(.., CMSG_HASH_ALGORITHM_PARAM, ...). Хэш по ГОСТ Р 34.11-94 всегда имеет длину 256 бит. | ||||
| ||||
>CryptMsgGetParam(.., CMSG_HASH_ALGORITHM_PARAM, ...). в эту функцию передается хендл сообщения, то есть эта функция находит значение алгоритма по какому-то идентификатору (или OID), прав я или нет, и если да то не могли бы Вы подсказать этот идентификатор. Спасибо. | ||||
| ||||
Местонахождение информации об алгоритме подписи определяется структурой сообщения PKCS7, а не идентификатором. | ||||
| ||||
А не подскажите в каком RFC это можно посмотреть (вроде бы в RFC2630, но точно не поню). И каким образом по структуре файла PKCS#7 можно распознать алгоритм? | ||||
| ||||
Да, 2630. Я не сказал что алгоритм хэширования определяется структурой PKCS7. Я имел ввиду, что место расположения информации об алгоритме определяется не идентификатором, а структурой PKCS7. Но сам алгоритм конечно определяется идентификатором, который находится в сообщении. | ||||
| ||||
>сам алгоритм конечно определяется идентификатором, который находится в сообщении. а какой идентификатор используется в Крипто-Про? | ||||
| ||||
#define szOID_CP_GOST_R3411 "1.2.643.2.2.9" | ||||
| ||||
это для обоих гостов? Если нет, то можно еще уточнить для госта Р 34.10-2001. | ||||
| ||||
Да, для обоих. При подписи по 94 и 2001 используется одинаковый алгоритм хэширования. | ||||
| ||||
Здравствуйте Кирилл. Вы писали: >Хэш по ГОСТ Р 34.11-94 всегда имеет длину 256 бит а длинна открытых ключей ГОСТ Р 34.11-94 так же всегда 256 бит? | ||||
| ||||
ГОСТ Р 34.11-94 - описывает алгоритм хэширования. Вы наверное имели ввиду ГОСТ Р 34.10-94 - там длина ОК 1024 бит. | ||||
| ||||
Да Вы правы я имел ввиду ГОСТ Р 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. Возможно я Вас не так понял? | ||||
| ||||
Не так поняли. Само наличие этого идентификатора в сообщении говорит о том, что использовался алгоритм ГОСТ Р 34.11-94. Значение NULL присутствует т.к. у него нет параметров. В PKCS7 1м случае это информация о собственно алгоритме хеширования, а во 2м - об алгоритме подписи (комбинация ГОСТ Р 34.11-94 и ГОСТ Р 34.10-2001) | ||||
| ||||
Хм. >комбинация ГОСТ Р 34.11-94 и ГОСТ Р 34.10-2001. А каким образом эти два госта комбинируются? Потому что мне не совсем понятно, если успользуется алгоритм ГОСТа Р 34.11-94 длинна хеша, как вы писали "всегда 256 бит", а как видно выше длинна уже существующего хеша = 512 бит. | ||||
| ||||
Как они комбинируются собственно в ГОСТ Р 34.10-2001 и описано. То что выше - это уже преобразованный хэш, у него длина равна длине ОК. | ||||
| ||||
То есть если я Вас правильно понял, то в функцию CryptVerifySignature() или CPVerifySignature, можно передавать хеш из файла, не смотря на то что размеры у вновь расчитанного хеша не совпадают? Или же хеш из файла подлежит какой-либо обработке перед передачей в данные функции? Не могли бы Вы указать ссылку гле можно найти описание ГОСТ Р 34.10-2001 и по возможности ГОСТ Р 34.10-94. Заранее благодарю. | ||||
| ||||
Конечно можно, если Вы не используете PKCS7, никакой обработки не надо. Про замечание насчет размеров не понял. Вот здесь есть описание http://www.password-crackers.com/crypto.html | ||||
| ||||
За ссылку спасибо (только по видимуму у них какие-то проблемы, ни одна ссылка не работает). Про размеры хешов: насколько я понял, хеш который я приводил выше по OID'ам Гост Р 34.11-94, и его длинна 32 байта, и к нему еще добавляется еще какая-то инфа и после этого его длинна изменяется до 64 байт, правильно? И если я использую функцию CPVerifySignature, то мне нужно выделить только хеш, без добавочной информации. | ||||
| ||||
Отправил Вам то, что когда-то оттуда скачал. Не к хэшу добавляется какая-то инфа, а хэш преобразуется по алгоритму ГОСТ Р 34.11-94 с помощью секретного ключа подписчика. | ||||
| ||||
Спасибо. У меня вот еще такой вопрос: если функция CPImportKey возвращает значение true, то я могу быть уверен что блоб открытого ключа /который передается в функцию как входной параметр/ правилен, если я его "собираю" его вручную. | ||||
| ||||
Если имеется ввиду функция, реализованная в КриптоПро СSP, то да, можете. | ||||
| ||||
Здравствуйте. >хэш преобразуется по алгоритму ГОСТ Р 34.11-94 с помощью секретного ключа подписчика. Обратная операция производится через открытый ключ подписчика, и при вызове функции CPVerifySignature выполняется автоматически? И еще вопрос: в функцию CPVerifySignature( HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE* pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags ) в качестве входного параметра pbSignature передается значение хеша или же подпись целеком? | ||||
| ||||
Да. Подпись целиком. | ||||
| ||||
То есть входной параметр функции верификации, указанный выше, составляется из последовательного "скрепления" байтов,которые добавляются в исходный файл в том же порядке в котором они встречаются в файле? | ||||
| ||||
Не понял Вашего вопроса. В том примере, который Вы привели, 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 - дескриптор объекта, в котором содержится хэш от исходного документа | ||||
| ||||
Ну в принципе это я и хотел увидеть. Спасибо. | ||||
| ||||
Здравствуйте. Ранее в этом топике я задавал Вам вопрос на счет функции CPImportKey (...возвращает значение true, то ...), для всех остальных функций реализованных в КриптоПро СSP, я так же могу быть уверенным что значения входных и выходных параметров корректны. И еще вопрос: Когда создается хеш функцией CPCreateHash() в качестве алгоритма передается алгоритм хеширования, а не подписи? /И именно для примера указанного выше он должен быть равным 32978/ | ||||
| ||||
Да, в функцию создания хэша передается именно алгоритм хэширования :) | ||||
| ||||
Тогда подскажите, что я не так делаю: 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, и функциями с этим же префиксом верифицируется. | ||||
| ||||
Судя по размеру подписи она у Вас на 2001 ГОСТе, при этом Вы используете "Crypto-Pro GOST R 34.10-94 Сryptographic Service Provider". | ||||
| ||||
Попробовал, не работает. Вот что поменял: подгрузил другую библиотеку (так как я на данный момент пользуюсь КриптоПро 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. | ||||
| ||||
А что GetLastError говорит? | ||||
| ||||
На счет подписи. 1) Подписью, на сколько я понял, является хеш, преобразованный на закрытом ключе подписчика? 2) Не совсем ясно как Вы определили ГОСТ по размеру подписи? | ||||
| ||||
>А что GetLastError говорит? он говорит "Код ошибки - 2148073478: Неправильная подпись." | ||||
| ||||
1)да 2)94 - 1024 бита, 2001 - 512 бит | ||||
| ||||
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 | ||||
| ||||
Да, и там и там используется ГОСТ Р 34.11-94. | ||||
| ||||
>...если Вы не используете PKCS7, никакой обработки не надо. Подскажите пожалуйста каким образом обрабатывается подпись полученная из файла PKCS#7, перед передачей в функцию верификации? | ||||