Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Удалось ли кому-нибудь средствами VFP при помощи Crypto API Крипто-Про подписать ЭЦП сформированный XML-файл?
Алгоритм таков: 1. Убеждаемся, что сертификат (открытый ключ ЭЦП Крипто-Про) установлен из файла .cer в персональное хранилище (personal). Если нет, то делаем DblClick на файле .cer и устанавливаем его. 2. Получаем контекст пользовательского сертификата (открытого ключа), не обращая внимание на наличие корневых сертификатов на компьютере подписанта:
На сайте у Анатолия Могилевца, находим описание типов и немного полезной информации:
P.S.: В документе "Методические рекомендации по разработке электронных сервисов и применению технологии электронной подписи при межведомственном электронном взаимодействии. Версия 2.4.4 (исправлены технические ошибки версии 2.4.3)", доступном для загрузке по ссылке: smev.gosuslugi.ru, на стр.41 указано: "К элементу <soapenv:Body> и его потомкам, включая атрибуты, применяется каноникализация www.w3.org#, на основе результата рассчитывается хэш по алгоритму ГОСТ Р 34.11-94 и заносится в <dsigestValue> в формате Base64." Для реализации алгоритма ГОСТ Р 34.11-94 необходимо и достаточно переписать на VFP функцию:
Также, стоит задача, как преобразовать pbyte в строку UTF-8 и закодировать ее в формате Base64, т.е. нужно написать прямую и обратную процедуры для перекодировки: ? decode_base64(encode_base64(encode("UTF-8", "Тестовая строка"))) Как известно, в VFP есть функция перекодировки в UTF-8:
Исправлено 5 раз(а). Последнее : rvc44, 01.07.12 08:19 |
Re: Подпись XML (СМЭВ) | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Там же есть и кодирование/декодирование base64 - 2 параметр =13 и 14 в функции STRCONV - но только не ФАЙЛА а строки - а уж поместится ли твой файл в фоксовую строку, или вылезет за лимит - это только тебе известно... ------------------ WBR, Igor |
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Спасибо, Игорь! Раньше в VFP максимальная длина строки была равна 255 символов, а теперь стала 64 Kb! Так что, нужно просто следить за тем, чтобы XML-файл не превышал этот размер... вот и всё!
Насчет двух недостающих деклараций API-функций, как выяснилось на практике получается вот так:
Исправлено 4 раз(а). Последнее : rvc44, 05.07.12 00:36 |
Re: Подпись XML (СМЭВ) | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Максимальная длина строковой переменной (что и имеет значение в данном случае) в VFP чуть менее 16Мб - по крайней мере начиная с VFP5. В принципе через FILETOSTR можно получить и более длинную строку, но вот работать с ней скорее всего не выйдет (большинство функций откажутся с ней работать). Учитывая что base64 увеличивает размер обрабатываемого объекта (массива байт/строки - это не суть важно) на треть (каждые 3 байта кодируются 4-мя символами) и что UTF8 преобразует русские буковки в 2-х байтные последовательности (английские буковки, цифры и большая часть спецсимволов - пробелы там, кавычки с точками и т.п. остаётся 1-байтными), то взяв наихудший случай можно посчитать, что для подобного двойного преобразования исходный "текст" (совсем неважно XML там или нет) должен быть не более 6Мб. Если он больше, то нужно уже использовать иные средства преобразования. Ещё можно использовать вместо строковой переменной memo-поле, для него пределом будет чуть менее 2Гб - но это уже из разряда извращений, да и не уверен я что STRCONV сможет его нормально пережевать.
------------------ WBR, Igor |
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Надо же, действительно, больше 64 Kb! А я раньше считал это лимитом. Известный разработчик VFP Rick Strahl написал статью 19.01.2012 "How to work around Visual FoxPro's 16 Megabyte String Limit": www.west-wind.com. Можно почитать, кому интересно!
|
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Есть ли у кого возможность проверить мой следующий код для поиска установленных сертификатов в системе, в котором изпользуется стандартное Crypto API:
Исправлено 1 раз(а). Последнее : rvc44, 06.07.12 19:04 |
Re: Подпись XML (СМЭВ) | |
---|---|
dimuhametov Сообщений: 1562 Откуда: Костанай Дата регистрации: 01.11.2008 |
Аналогично CertFindCertificateInStore возвращает 0 , хотя 2 сертификата GOST и RSA установлены в системе.
------------------ Незнание делает жизнь такой интересной. |
Re: Подпись XML (СМЭВ) | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Мануал говорит про использование UNICODE строк. У меня фокс вываливается в C005 вскоре после подобного издевательского обмана системы - нужно то было писать
P.S. После подобного исправления у меня лично находит имеющийся в хранилище "личный" сертификат. ------------------ WBR, Igor |
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Браво!
+1, Игорь, как всегда! Низко кланяюсь... Это как раз то, что я сегодня целый день искал. Теперь, если переопределить 5-й параметр через STRING в
CN сертификата можно посмотреть в Windows оснастке certmgr.msc для тех, у кого не установлен CryptoPro (последняя версия 3.6), либо в оснастке "Сертификаты" от CryptoPro. CryptoPro необходим для подписывания передаваемых XML-файлов по алгоритму ГОСТ Р 34.11-94 (CALG_GR3411). Разработка темы продолжается... Конечно, есть еще непонятные вопросы, например, как в фоксе выделять память при поиске сертификата по hash (#DEFINE CERT_FIND_HASH 0x00010000), рассмотренной меньше недели назад на форуме Крипто-Про: ats.cryptopro.ru ... но, по крайней мере, радует то, что это работает не только в C++, C#, Delphi, но и под VFP (если очень захотеть, и когда на FoxClub'е есть такие люди как Игорь!) |
Re: Подпись XML (СМЭВ) | |
---|---|
Влад Колосов Сообщений: 22664 Откуда: Ростов-на-Дону Дата регистрации: 05.05.2005 |
У меня по-прежнему не находит.
------------------ Совершенство - это не тогда, когда нельзя ничего прибавить, а тогда, когда нечего убавить. |
Re: Подпись XML (СМЭВ) | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Плоская структура без наворотов - делается тривиально - никакого специального выделения памяти в этом случае не требуется.
------------------ WBR, Igor |
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Влад, а твой сертификат точно в разделе "текущий пользователь", как показано на скриншоте?
[attachment 13759 Cert.JPG] После успешной отработки функции CertFindCertificateInStore, т.е. если сертификат найден, можно получить и вывести имя субъекта сертификата:
Исправлено 1 раз(а). Последнее : rvc44, 05.07.12 18:31 |
Re: Подпись XML (СМЭВ) | |
---|---|
dimuhametov Сообщений: 1562 Откуда: Костанай Дата регистрации: 01.11.2008 |
Аналогично, как у Влада, CertFindCertificateInStore возвращает 0
[attachment 13763 1.jpg] ------------------ Незнание делает жизнь такой интересной. |
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Тогда проверьте, работает ли у вас следующий код для поиска и вывода названий ВСЕХ сертификатов, установленных в персональном хранилище MY:
У меня он замечательно отрабатывает! |
Re: Подпись XML (СМЭВ) | |
---|---|
Влад Колосов Сообщений: 22664 Откуда: Ростов-на-Дону Дата регистрации: 05.05.2005 |
А вот этот код находит!
------------------ Совершенство - это не тогда, когда нельзя ничего прибавить, а тогда, когда нечего убавить. |
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Ну тогда попробуйте копипастить и выполнить еще раз код из 6-го поста сверху. Раньше этот код был не поправлен с учетом замечания Игоря Королёва. Сейчас я ошибку в коде специально поправил и он должен работать "как есть". Имена сертификатов данный код не выводит, но, по крайней мере, он должен писать, что "Сертификаты найдены!"... Проверьте, пожалуйста, ещё раз, чтобы точно убедиться! Неужели функция CertFindCertificateInStore на некоторых компьютерах не отрабатывает? Мне важно знать об этом...
|
Re: Подпись XML (СМЭВ) | |
---|---|
dimuhametov Сообщений: 1562 Откуда: Костанай Дата регистрации: 01.11.2008 |
Теперь оба алгоритма отработали на отлично ! Сертификаты найдены ! Спасибо. ------------------ Незнание делает жизнь такой интересной. |
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Сегодня мне удалось, поколдовав немного с памятью, переложить на VFP код, определяющий для текущего пользователя (либо компьютера) имя криптопровайдера (CSP) по умолчанию:
У меня этот код посредством двойного обращения к API-функции CryptGetDefaultProvider сначала определяет длину имени криптопровайдера по умолчанию (в моём случае она составляет 60 символов), а затем и имя самого криптопровайдера: Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider Проверяйте, что возвращает этот код у вас... |
Re: Подпись XML (СМЭВ) | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Это уже горе от ума. Не надо тут заморачиваться с ручным рулением памятью, фокс и сам прекрасно справится - декларация на сайте правильная. При том вполне логично попытаться за 1 вызов всё получить, а не дёргать 2 раза только чтобы сэкономить пару сотен байтиков
Естественно что "у нас" никаких PROV_GOST_* и в помине нету А вот RSA по идее в любой NT есть - под очень старыми, правда, будет чуток порезанный, а под новыми уже Strong. ------------------ WBR, Igor |
Re: Подпись XML (СМЭВ) | |
---|---|
rvc44 Автор Сообщений: 2211 Откуда: Тамбов Дата регистрации: 06.12.2005 |
Итак, собственно, добрались до кульминационного момента данной темы - формирования электронной подписи документа (ЭЦП). Зарегистрированные в системе идентификаторы объектов (OID'ы) алгоритмов находятся в следующем разделе реестра:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo Подпись документа осуществляется при помощи функции API CryptSignMessage из crypt32.dll. Подписывать XML-файл будем отдельной от данных (detached) сигнатурой. Для тех, у кого загружен и установлен пакет Крипто-Про (загрузка и установка бесплатны), для СМЭВ в РФ можно и нужно использовать алгоритм с OID = '1.2.643.2.2.3'. При отсутствии пакета Крипто-Про можно использовать алгоритм цифровой подписи MD5 с OID = '1.2.840.113549.1.1.4'. 3-я цифра в OID: 643=РФ, 840=US. С наложением электронной подписи на документ на VFP у меня пока не всё "срослось", есть проблемы... Обратите внимание на приведенное в коде определение структуры CRYPT_SIGN_MESSAGE_PARA и сформированную на основе её переменную SignPara. Не вполне понятно, что должно быть указано вместо PtrCertContext? Декларация функции CryptSignMessage достаточно сложная и отличается от других тем, что её 4 и 5 параметры являются массивами, что в API-функциях встречается не часто. 4-й параметр rgpbToBeSigned представляет собой массив данных, передаваемых для формирования цифровой подписи, а 5-й параметр rgcbToBeSigned представляет собой массив размеров элементов переданного массива данных. Как раз с этими массивами, по моему, в VFP и возникают проблемы, поскольку API использут zero-based массивы, а VFP использует one-based массивы. Конечно, существует функция COMARRAY(oObject, 10+1000), но она применяется только для COM-объектов. Для массивов можно либо написать обёртку на VFP+JScript, способом показанным здесь: hттp://forum.foxclub.ru/read.php?29,271311 (пока не знаю, стоит ли это пробывать? уж что только не перепробывал!), либо можно создать пустой zero-based вариантный массив, как показано ниже, но похоже, этот способ исправления ситуации не подходит, поскольку создаваемый "объект" в контексте остального кода не уместен:
Исправлено 2 раз(а). Последнее : rvc44, 16.07.12 20:01 |
© 2000-2024 Fox Club  |