logo
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline Dartwed1989  
#1 Оставлено : 17 мая 2019 г. 11:38:52(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

Добрый День!

Подписываю файл XML с помощью XMLDSig, сервер портала системы электронных паспортов(СЭП) возвращает сообщение - "Подпись некорректна".
Пробовал на версиях платформы 1С 8.3.10.2496 и 8.3.12.1531.

Подписываю файл следующим образом:
1. Есть сертификат УЦ с алгоритмом подписи GOST R 34.11-2012/34.10-2012 256 bit, Алгоритм Хэш GOST R 34.11-2012 256 bit.
Открытый ключ: ГОСТ Р 34.10-2012 256 бит. Идентификатор 1.2.643.7.1.1.1.1
Подпись удостоверяющего центра: ГОСТ Р 34.11-2012/34.10-2012 256 бит. Идентификатор 1.2.643.7.1.1.3.2
В параметрах XMLDsig в 1С прописал следующее:
ИмяАлгоритмаПодписи = "GR 34.10-2012 256";
OIDАлгоритмаПодписи = "1.2.643.7.1.1.3.2" - если прописать 1.2.643.7.1.1.1.1, то 1С ругается, что OID алгоритма подписи не соответствует OID компоненты.
ИмяАлгоритмаХеширования = "GR 34.11-2012 256"
OIDАлгоритмаХеширования = "1.2.643.7.1.1.2.2"

XPathПодписываемыйТег = "(//. | //@* | //namespace::*)[ancestor-or-self::soapenv:Envelope]"; По требованиям СЭП подписывать необходимо весь конверт целиком.
XPathSignedInfo = "(//. | //@* | //namespace::*)[ancestor-or-self::*[local-name()='SignedInfo']]";

2. После сбора всех данных в 1С формирую строку XML, которую буду подписывать(см. Строка для подписи)
Параллельно формирую строку XML, в которую буду вставлять подпись (см. Строка с тэгами подписи). Строки абсолютно идентичны, только во второй есть тэги подписи.
3. Каноникализация строки для подписи(см. Строка для подписи каноникализация)
4. Во вторую строку выгружаю данные сертификата в тэг X509Certificate, вставляю рассчитанный хэш в тэг DigestValue и саму подпись в тег SignatureValue. Данные отправляются в СЭП(см. Итоговый конверт отправки, Ответ СЭП)
Возвращается ответ - Подпись некорректна. В чем именно проблема разобраться не выходит. Тех поддержка СЭП ответить на вопрос не может.
Если получится помочь, буду крайне признателен.
Offline Максим Коллегин  
#2 Оставлено : 20 мая 2019 г. 12:10:12(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 5,519
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 11 раз
Поблагодарили: 524 раз в 475 постах
Выложите по возможности примеры "хорошего" и "плохого" подписанного xml. Попробуйте поиграть с PreserveWhitespace.
Знания в базе знаний, поддержка в техподдержке
Offline Dartwed1989  
#3 Оставлено : 20 мая 2019 г. 17:09:40(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

К сожалению "хорошего" xml нет.
Ресурс https://www.justsign.me/verifyqca/Verify/ так же показывает, что подпись недействительна.
Offline two_oceans  
#4 Оставлено : 21 мая 2019 г. 8:14:58(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 367
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 26 раз
Поблагодарили: 88 раз в 85 постах
Похоже вложения не прикрепились. Попробую предположить вслепую, что Вы делаете подпись через низкоуровневые функции или плагин и сами собираете тег Signature - нужно проверить положение вставленного тега подписи Signature и вставленный текст, возможно вставляете не то и не туда. По идее при подписании всего документа (предполагаю что кроме SOAP:Envelope и вложенных в него тегов больше ничего нет в документе), он должен располагаться в конце документа перед
Код:
</SOAP:Envelope>
, в референс указывается URI="" и в список трансформов под референсом добавляется урл трансформа enveloped signature. Трансформ enveloped signature показывает что подпись (подписи), располженную непосредственно под подписываемым тегом надо удалить при проверке перед расчетом хэша, без него в расчет хэша попадет и сама подпись следовательно хэш не сойдется, так как Вы считали хэш еще без подписи. Также не забудьте проверить, что текст SignedInfo не изменяется в процессе ручной сборки подписи после вычисления SignatureValue (лучше вообще вставить именно каноникализированный текст SignedInfo, от которого вычислено SignatureValue в готовую подпись). Также лучше избегать переводов строк с символом 13 в SignedInfo, разными системами стандарты применяются в разном порядке и есть различия в обработке символов с кодом 13. В идеальном случае символы 13 должны быть удалены перед каноникализацией в процессе "нормализации" документа, то есть каноникализация их вообще не должна обрабатывать при наложении подписи. Если несмотря на все это, все равно ошибка проверки, то возможно каноникализация проведена неверно.

Кстати, возможен еще вариант с "переворотом" значений хэша и/или подписи - в зависимости от криптопровайдера результат может быть "задом наперед" от требуемого XMLDSig формата и нужно поменять первый байт с последним, второй с предапоследин и т.д до середины перед переводом значения в Base64. Если плагин Вам результат выдал уже в Base4 то надо декодировать, перевернуть и снова закодировать. При длине 256 хэш должен заканчиваться один знаком =, а значение подписи двумя знаками ==. В случае гост-2001 и низкоуровневыми функциями нужно было перевернуть хэш, а значение подписи записать как есть без переворота. По гост-2012 было сообщение что порядок тот же, но у меня что-то тоже не сходится подпись, а верных примеров с гост-2012 для "калибровки" маловато, жду пока смэв начнет подписывать новым гост.

Если нужно, могу прогнать Ваши примеры через свою программку и уточнить на каком этапе проверки возникает ошибка.
Offline Dartwed1989  
#5 Оставлено : 21 мая 2019 г. 8:38:20(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

Stroka s tehgami podpisi.xml (27kb) загружен 3 раз(а). Stroka dlja podpisi.xml (26kb) загружен 4 раз(а). Stroka dlja podpisi kanonikalizacija.xml (39kb) загружен 5 раз(а). Itogovyjj konvert otpravki.xml (30kb) загружен 4 раз(а). OtvetSEhP.xml (5kb) загружен 2 раз(а).

Файлы перезалил
Offline two_oceans  
#6 Оставлено : 22 мая 2019 г. 7:37:52(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 367
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 26 раз
Поблагодарили: 88 раз в 85 постах
Посмотрел файлы. Какая-то смесь разных требований если честно, пройти может только первый этап проверки подписи (проверка правильности SignatureValue), хэши в таком виде документа не могут сойтись. Попробую их проверить чуть позже, слегка изменив документ, а пока перечислю странности документа.

1.
Исправлено: после перепрочтения текста стандарта в сообщении ниже уже не уверен в своем понимании трансформа enveloped signature, поэтому убрано в спойлер

Еще отмечу, что несмотря на удаление тега Signature и вложенных в него тегов трансформом enveloped signature, в подписываемом тексте должны сохранятся все остальные теги. В данном случае я вижу что в строке для подписи отсутствует тег SenderInformationSystemSignature, по стандартам он должен присутствовать (пусть и пустой), так как он тоже не удалится трансформом enveloped signature.

2. Важно то, что CanonicalizationMethod Algorithm применяется только к SignedInfo перед выработкой SignatureValue и ничего не говорит о каноникалилации тега на который ссылается референс перед вычислением DigestValue. Поэтому если Вы текст документа за исключением текущей подписи каноникализируете, то в трансформах должен присутствовать и метод каноникализации. Иначе при проверка каноникализация скорее всего не будет выполнена и получится другой хэш.

В принципе проверяющая сторона может выбрать некий алгоритм каноникализации по умолчанию, который используется когда никакого не указано. Например, чтобы проверить все примеры разных ГИС моя программа подбирает трансформ каноникализации хэша когда никакого не указано в трансформах референса, но выдает предупреждение что фактически использован такой-то алгоритм каноникализации при том что никакого не указано. Однако это уже натяжка стандарта под конкретные ГИС, лучше укаать явно какой алгоритм каноникализации Вы использовали перед вычислением хэша чтобы проверка точно прошла успешно.

Сразу скажу по порядку трансформов когда их несколько в одном референсе: в случае присутствия трансформа enveloped signature сначала указавается enveloped signature потом метод каноникализации. Если присутствует смэвовский трансформ он указывается после канононикализации. При другом порядке трансформы дают неожиданный результат.

3. Формат начиная с RequestMessage очень напоминает схемы СМЭВ3 (хотя и отличия есть, например MessageID не по требования смэв3 из метки времени и мак адреса, а сгенерирован случайно), по которым в SenderInformationSystemSignature помещается подпись от элемента SenderProvidedRequestData, а не от SOAP:Envelope.

Возможно нужно наложить две подписи - одну по требованиям смэв (в SenderInformationSystemSignature поместить подпись от элемента SenderProvidedRequestData с определенными смэв трансформами: исключающая каноникализация и смэвовский, при этом SenderProvidedRequestData должен иметь Id начинающийся с буквы и этот Id указывается в референс ури после решетки), вторую в конце документа, перед </SOAP:Envelope> с URI="" и трансформами: enveloped signature и каконикализацией. Обратите внимание, что при наложении подписей на теги вложенные один в другой важно соблюдать порядок наложения подписей - сначала подписать вложенный тег потом обрамляющий тег (но без исключения подписи вложенного тега).

Другой вариант - что вторая подпись накладывается на какой-то другой из тегов (SOAP:Body или EPLTSAddData или RequestMessage). Это все же нужно уточнить в требованиях предъявляемых конкретной ИС. Либо все-таки какой-то правильный пример из руководства пользователя хотелось бы посмотреть чтобы не гадать.

Отредактировано пользователем 22 мая 2019 г. 12:19:14(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
Андрей Писарев оставлено 22.05.2019(UTC)
Offline Dartwed1989  
#7 Оставлено : 22 мая 2019 г. 9:57:41(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

example.xml (239kb) загружен 6 раз(а).


СЭП прислал корректный файл с подписью
Offline two_oceans  
#8 Оставлено : 22 мая 2019 г. 12:14:57(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 367
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 26 раз
Поблагодарили: 88 раз в 85 постах
Хм, или я неправильно понимаю трансформ enveloped signature или что-то тут не так.


Ну хорошо, пусть текущая подпись (содержащая алгоритм enveloped signature) убирается где бы ни была, тогда навскидку вижу отличия: 1) нет XML Declaration
Код:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
Ваши файлы вроде бы уже в UTF-8, но без данной строки в начале (строка должна появиться в итоговом варианте, в остальных может отсутствовать, так как все равно удаляется при каноникализации); 2) все же надо вставить пустой тег SenderInformationSystemSignature в строку для подписи; 3) замечание про указание каноникализации из прошлого моего ответа все равно может быть в силе (хоть трансформ каноникализации не указан в примере, может быть не лишним его указать).

Сейчас изменю трансформ в своей программе и попробую проверить на предмет порядка байтов.

Отредактировано пользователем 22 мая 2019 г. 12:20:52(UTC)  | Причина: Не указана

Offline two_oceans  
#9 Оставлено : 23 мая 2019 г. 13:27:47(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 367
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 26 раз
Поблагодарили: 88 раз в 85 постах
Спасибо за пример, помог мне заодно разобраться с гост-2012.

Так как пример прошел проверку на КриптоПро DSS, то использовал его для калибровки гост-2012. Попробовал провести пример через проверку и завалился сразу на проверке SignatureValue. Как оказалось, у меня инициализировался по умолчанию хэш гост-94 при типе провайдера 80 и подавался на проверку с дескриптором открытого ключа из сертификата гост-2012 и низкоуровневая функция проверки о несовместимых алгоритмах даже не пикнула, просто проверила по гост-2001 надо полагать и выдала результат: неверная подпись.

С поправкой алгоритма хэша на гост-2012-256 проверка SignatureValue в примере прошла, а в Вашем итоговом конверте все равно пока не проходит, попробую разнын варианты с сохранением удалением символов с кодом 9,10 и разным порядком байт. Для устойчивости прохождения проверки во всех средствах проверки было бы замечательно чтобы в SignedInfo вообще не было символов с кодами ниже 32 (другими словами, табуляций и переводов строк, так как остальные символы с кодами наже 32 и так уже запрещены форматом XML).
Offline Dartwed1989  
#10 Оставлено : 24 мая 2019 г. 14:48:35(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

По "правильному" файлу можно ли определить данные в каких тегах подписываются?
Offline Dartwed1989  
#11 Оставлено : 24 мая 2019 г. 16:00:39(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

XW7BDREV10S045760_Registracija_Zapros.xml (30kb) загружен 3 раз(а).


Обновил подпись файла согласно Вашим комментариям. Добавил строку сверху и включаю в расчет хеша тег SenderInformayionSystemSignature. Кроме этого убрал все проблемы в структуре подписи. Файл приложил.
Можно ли узнать на каком этапе проверки подписи возникает ошибка?
Offline two_oceans  
#12 Оставлено : 27 мая 2019 г. 7:21:22(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 367
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 26 раз
Поблагодарили: 88 раз в 85 постах
Автор: Dartwed1989 Перейти к цитате
По "правильному" файлу можно ли определить данные в каких тегах подписываются?
По "правильному" файлу в референсе также указывается URI="" и enveloped-signature, то есть подписывается весь нормализованный документ за исключением Signature и вложенных в Signature тегов. Тем не менее алгоритм каноникализации в референсе отсутствует, что вызывает неоднозначность обработки.

Нормализованный - это значит, что все последовательности символов 13 затем 10 (переводы строк Windows) заменяются на одиночный символ 10, одиночные символы 13 (переводы строк Mac) заменяются на одиночные 10, то есть все переводы строк будут только 10. Если перед тегом Signature и сразу после него есть "текстовые узлы" (включая "whitespace" - табуляцию или переводы строк, пробелы), текстовые узлы остаются в тексте передаваемом на обработку.

Далее алгоритм каноникализации обрабатывает и удаляет теги начинающиеся с вопросительного знака - инструкции обработки и xml декларацию, заменяет последовательности начинающиеся со знаков амперсанда и процента. Комментарии могут оставаться или исключаться (меняется урн метода в документе). Кодировка приводится к UTF-8. При эксклюзивной нормализации тем не менее можно указать параметр InclusiveNamespaces со списком префиксов пространств имен, к которым применится неэксклюзивный вариант (под тегом CanonicalizationMethod или Transform добавляется тег InclusiveNamespaces, адрес пространства имен равно идентификатору эксклюзивной каноникализации). Параметр PreserveWhitespace позволяет подобрать вариант обработки пробелов и табуляций - оптимизировать или оставить как есть, это параметр вроде бы не отражается в тексте документа, приходится подбирать.

У меня по умолчанию при отсутствии каноникализации стояло применение C14N (неэксклюзивного варианта). Отключил неэксклюзивный вариант, получилось вообще без преобразований после исключения подписи - хэш "правильного" файла не сходится. Попробую изменить на эксключивный вариант.

С новым вариантом XW7BDREV10S045760_Registracija_Zapros.xml - тоже самое, теперь SignedInfo без переводов строк и значение SignatureValue прошло проверку, но с хэшем пока что-то не то.

Отредактировано пользователем 27 мая 2019 г. 7:24:24(UTC)  | Причина: Не указана

Offline Dartwed1989  
#13 Оставлено : 27 мая 2019 г. 17:35:40(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

Я думаю, проблема в том, что встроенная компонента 1С, которой я пользуюсь некорректно каноникализирует строку XML из-за того что передается неправильный путь xPath.

Я описывал в первом сообщении, что подписываю одну строку xml, а хэш и подпись вставляю в другую. Делал я так только потому, что мне не удалось сформировать путь XPATH, который бы исключал теги подписи при каноникализации строки с данными. В типовом варианте работы этой процедуры используется одна строка xml, содержащая все данные и теги подписи. Встроенная компонента 1С, которая каноникализирует xml работает по принципу черного ящика. Знаю лишь, что используется C14N(). На вход подается строка xml и тег xpath для получения каноникализированного текста.

В итоге я решил доработать типовую процедуру для работы с двумя xml файлами - в одном все данные, кроме тегов подписи(но включая теги SenderInformationSystemSignature), в другой строке те же данные + теги подписи Sygnature. В итоге Хэш все равно неправильный.

Мне кажется, что надо вернуться к типовому виду данной процедуры 1С, но правильно передать на вход путь XPATH для подписываемых данных. К сожалению, такой путь сформировать у меня не получается.




Offline two_oceans  
#14 Оставлено : 28 мая 2019 г. 5:29:15(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 367
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 26 раз
Поблагодарили: 88 раз в 85 постах
К сожалению, в построении XPath я не силен. Скорее всего для целого документа должно быть что-то простое вроде //* Каноникализация по идее и не должна выкидывать Signature, это функция другого трансформа, применяемого перед каноникализацией. С другой стороны, если реализация позволяет, почему бы не совместить. Возможно надо добавить условие xpath на отрицание
Код:
ancestor-or-self::dsig:Signature
(это выборка Signature и его потомков, благо тег Signature один и можно не осторожничать). В одном из прошлых сообщений в этой теме я процитировал текст стандарта про трансформу enveloped-signature вместе с эквивалентным выражением xpath, возможно оно подойдет как есть.

На что я вчера обратил еще внимание - строку для подписи Вы прислали не нормализованную (с переводами строк Windows), а итоговый документ получился уже нормализованный (слипается в блокноте в одну строку, значит переводы строк только из символов с кодом 10). То есть посчитали хэш от строки с символами с кодом 13 (каноникализация их не удаляет, а заменяет на строку
Код:
&#xD;
), а потом отправляете итог без символов 13 (нормализация их меняет на 10). Еще момент в том, что после каноникализации у Вас символы 13 остались, то есть замена символов 13 похоже вообще не реализована в 1С (потому что их не должно быть в нормализованном тексте xml). По идее программа проверки хэша никак не узнает, что надо еще символы 13 примешать перед каноникализацией и да еще не заменять их и хэш получится другой. Другими словами, перед подачей строки для подписи Вам нужно либо строку для подписи загрузить во второй объект xml (такой же как тот, в котором собираете итоговый конверт, так как при загрузке строки обычно выполняется нормализация) и выгрузить обратно (также как формируте итоговый документ) либо вручную провести замены в строке для подписи chr(13) & chr(10) на chr(10), потом chr(13) на chr(10).

К сожалению, моя реализация эксклюзивной каноникализации явно неправильно работает на "правильном" файле: на входе 244560 байт, после enveloped трансформа 240868 байт, после нормализации 240453 байт, после каноникализации 911 байт (много тегов вообще выкинуто).

С другой стороны, на Вашем варианте более ожидаемый результат: вход 30540 байт (второй Ваш файл), после enveloped трансформа 26001 байт (значит тег Signature 4539 байт), после нормализации 26001 байт (уже нормализована), после каноникализации 35904 байт (увеличивается за счет объявлений пространств имен). Хотя как минимум вижу одну ошибку в своем результате с тегом RequestMessage (из-за того, что он без префикса и пустой префикс не объявлен, это скорее всего не соответствие схеме, хотя в "правильном файле" также) и моя реализация добавляет объявление xmlns="", которое не нужно если выше еще нигде не было xmlns=. Попробую сравнить свой каноникализированный вариант первого файла с Вашим и с эталоном (программка на .NET 4.5), может быть еще отличия найдутся.

Отредактировано пользователем 28 мая 2019 г. 5:47:13(UTC)  | Причина: Не указана

Offline Dartwed1989  
#15 Оставлено : 29 мая 2019 г. 16:21:05(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

KonvertSOAPItogV1S.txt (29kb) загружен 2 раз(а). KonvertSOAPItogVSEhP.xml (30kb) загружен 1 раз(а). KonvertSOAP.txt (28kb) загружен 7 раз(а). KonvertSOAPKanonikalizacija.txt (37kb) загружен 6 раз(а).
Добрый день!

Я немного переделал программу. Теперь получается следующее:

1. Получаю строку xml с данными и с тегами подписи(см. КонвертSOAP). Я просто скопировал строку, которая получается в программе в текстовый файл и приложил к сообщению.
2. Каноникализация данной строки. У меня получилось составить XPath таким образом, чтобы тег Signature не учитывался. Получилось следующее - см. КонвертSOAPКаноникализация. К сожалению, компонента 1С, которая производит каноникализацию строки выдает ошибку, если в строке XML есть <?xml version="1.0" encoding="UTF-8" standalone="no"?>. Поэтому каноникализирую без этой строки. Затем просто добавляю ее в начало итоговой строки. Запросил у 1С почему так, жду ответ. Пробовал не добавлять, подпись все равно в итоге не верна.
3. После каноникализации рассчитывается хэш и подпись и вставляется в эту же строку xml. Приложил файл КонвертSOAPИтогВ1С - это то, что у меня получается непосредственно в программе, до сохранения в файл xml. И сам итоговый файл xml, который передаю в Систему электронных паспортов.

Перед каноникализацией сохраняю строку в xml файл с форматом UTF-8, затем дополнительно убираю символы с кодом 13 если они есть.
Offline two_oceans  
#16 Оставлено : 30 мая 2019 г. 8:34:09(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 367
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 26 раз
Поблагодарили: 88 раз в 85 постах
1. После беглого просмотра - во всех файлах txt присутствуют символы с кодом 13, в итоговом не присутствуют. То есть что-то кардинально меняется в xml. Символы 13 должны быть убраны до каноникализации, но раз каноникализация их игнорит, то хотя бы до вычисления хэша.

Тут конечно возможен вариант с сохранением файла копированием при котором добавляются символы, попробуйте не копировать, а сохранить из 1С. Кстати, насколько помню 1С хранит строки в win-1251 или даже в ascii (866), что не очень подходит для работы с подписанием xml. Чтобы перевести в UTF-8, желательно вывести текст в текстовый объект ADODB.Stream с кодировкой UTF-8, потом сохранить в файл (или перечитать строку из стрима). На VBScript выглядит примерно так (адаптируйте на русские названия методов/свойств под 1С, где-то тут уже была тема с адаптированным кодом):
Код:
Set ShtStream = CreateObject("ADODB.Stream")
    ShtStream.Mode = 3 'разрешение на чтение и запись
    ShtStream.Type = 2 'тип данных - 1 Binary 2 Text
    ShtStream.Charset = "UTF-8"
    ShtStream.Open
    ShtStream.WriteText S
    ShtStream.SaveToFile FN
    ShtStream.Close
    Set ShtStream = Nothing

Методом WriteText не вставляется переводов строк. FN имя файла, S выаодимый в файл текст.
Правда там тоже есть хитрость, в начало файла добавляется метка порядка байтов (3 байта для utf-8), которая должна быть выкинута при расчете хэша, поэтому сохраненный в тестовом режиме файл надо перечитать в двоичном типе данных ADODB.Stream с позиции 3 и сохранить снова, если идет на вычисление хэша.

2. Если добавлена строка <?xml с указанием кодировки UTF-8, то и фактическая кодировка переданного текста должна быть UTF-8. То есть если Вы подаете с этой строкой, но в другой кодировке - каноникализация закономерно выдаст ошибку (в utf-8 должна быть определенная последовательность байт, например, два символа кириллицы подряд в кодировке win-1251 вызовут ошибку при декодировании utf-8), скорее всего дело в этом, но могут быть еще нюансы специфичные для 1С. Перед каноникализацией и вычислением хэша нужно убедиться что фактическая кодировка текста utf-8.

3. Общий подход к программе звучит верно.

Отредактировано пользователем 30 мая 2019 г. 8:36:12(UTC)  | Причина: Не указана

Offline Dartwed1989  
#17 Оставлено : 31 мая 2019 г. 10:32:01(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

Добрый день!

Вчера у меня получилось подписать пустой файл. При этом я заметил некую странность работы компоненты 1С при каноникализации строки.

Подписываю xml строку следующего формата:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/><ds:Reference URI=""><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></ds:Transforms><ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/><ds:DigestValue>%DigestValue%</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>%SignatureValue%</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>%BinarySecurityToken%</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

Подпись вставляю в тег Header.

Каноникализация в 1С:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header></soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>

Данная каноническая форма xml соответствует форме, которую я получаю на другом онлайн ресурсе.
В результате, сервис https://www.justsign.me/verifyqca/Verify/ возвращает сообщение, что подпись математически корректна. При этом в коде 1С я воспользовался объектом ADODB.Stream и убрал метки порядка байтов. Правда позже выяснил, что при сохранении xml строки в файл формата utf-8 в 1с можно передавать параметр, который определяет наличие этих байтов. В общем, с нормализацией строки разобрался.
Кроме того, добавление строки "<?xml version="1.0" encoding="UTF-8" standalone="no"?>" в начало xml файла после подписи, никак не повлияло на конечный результат. Подпись корректна.

Однако.
Если попробовать подписать похожую пустую xml строку:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/><ds:Reference URI=""><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></ds:Transforms><ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/><ds:DigestValue>%DigestValue%</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>%SignatureValue%</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>%BinarySecurityToken%</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

В данной строке добавлено объявление пространства имен xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

Каноническая форма в 1С:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header></soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>

Каноническая форма на стороннем ресурсе:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header></soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>

Я заметил, что объявление пространства имен xmlns:xsi в канонической форме остается, а в 1С убирается.
В итоге подпись на ресурсе не проходит. Может быть проблема исключительно в этом? В файлах примерах, что я присылал ранее, пространства имен в канонической форме также убраны, а на стороннем ресурсе они остаются(перепроверил). Я не придал этому значения тогда.
К сожалению, мне пока не удалось на ресурсах 1С найти описание работы процедуры C14N() встроенной компоненты, запросил у тех поддержки описание, но пока ответа нет.
Посмотрел описание процедуры в гугле, но не понял, можно ли передавать какой-либо параметр на вход, чтобы на выходе не убирались пространства имен.


Offline two_oceans  
#18 Оставлено : 31 мая 2019 г. 13:28:10(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 367
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 26 раз
Поблагодарили: 88 раз в 85 постах
Автор: Dartwed1989 Перейти к цитате
Добрый день!
Вчера у меня получилось подписать пустой файл.
... добавление строки "<?xml version="1.0" encoding="UTF-8" standalone="no"?>" в начало xml файла после подписи, никак не повлияло на конечный результат. Подпись корректна.
Тут все понятно, рад что наметился прогресс. У этого примера как я понимаю одинаковые эксклюзивная и неэксклюзивная канонические формы.
Автор: Dartwed1989 Перейти к цитате
Однако. Если попробовать подписать похожую пустую xml строку:
...
В данной строке добавлено объявление пространства имен xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

Каноническая форма в 1С:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header></soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>

Каноническая форма на стороннем ресурсе:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header></soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>
Я заметил, что объявление пространства имен xmlns:xsi в канонической форме остается, а в 1С убирается.
Ну вообще я наверно на стороне 1С - неиспользуемое пространство имен должно быть выкинуто при эксклюзивной каноникализации (при неэксклюзивной вроде бы может и остаться). То есть тут есть отличие между каноническими формами и я (уже наверно в третий раз) предлагаю явно задать метод каноникализации дополнительным трансформом под референсом, после enveloped-signature. Хотя отдельный вызов каноникализации все равно его не обработает, но можно узнать какая все же у Вас форма и заставить другую сторону использовать такую же при проверке подписи. Для ясности: какую форму выбираете на стороннем сайте? Наверно можно наглядно прояснить это если взять такой пример:
Код:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
	<soapenv:Header xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:Signature/></soapenv:Header>
	<soapenv:Body></soapenv:Body>
</soapenv:Envelope>
Эксклюзивная форма перенесет объявление xmlns:ds вниз, а неэксклюзивная вверх. Если 1С и сторонний ресурс перенесут в разные стороны, то у них разные формы каноникализации.

Другой вопрос, если Вы добавите любой атрибут или тег с префиксом xsi тогда пространство будет использовано и оставлено в любой форме. В "правильном" файле эту нагрузку "удержания xsi" несет атрибут xsi:schemaLocation, однако мне кажется странным этот параметр использовать не в схеме, честно я бы выкинул и параметр и объявление xsi.
Автор: Dartwed1989 Перейти к цитате
Посмотрел описание процедуры в гугле, но не понял, можно ли передавать какой-либо параметр на вход, чтобы на выходе не убирались пространства имен.
Если нет атрибута или тега из пространства имен xsi, то можно было бы теоретически передать в эксклюзивную каноникализацию параметр InclusiveNamespaces со значением xsi, тогда скорее всего алгоритм его не выкинет. Как передать его в 1С остается вопросом, но параметр является частью стандарта.

Собственно, просто выкидыванием пространства xsi все равно не решить проблему, так как у Вас возможно то же самое будет с пространством ds, если поднимите его объявление на уровень выше как в "правильном" файле.

Отредактировано пользователем 31 мая 2019 г. 13:38:39(UTC)  | Причина: Не указана

Offline Dartwed1989  
#19 Оставлено : 3 июня 2019 г. 10:57:42(UTC)
Dartwed1989

Статус: Участник

Группы: Участники
Зарегистрирован: 17.05.2019(UTC)
Сообщений: 11
Российская Федерация
Откуда: Санкт-Петербург

XW7BDREV10S045760_Registracija_Zapros.xml (30kb) загружен 7 раз(а).
Добрый день!

У меня получилось настроить электронную подпись. Прикладываю файл, по которому сервис проверки подписи показал, что подпись корректна. Да и всистеме электронных паспортов не было ошибки по подписи.

Я указал в файле напрямую метод каноникализации(если я правильно все понял, то указан эксклюзивный вариант, по которому работает каноникализация в 1С) + не добавляю байты порядка файлов при сохранении в файл из 1С, и как следствие все работает.

Огромное спасибо за помощь!
Offline ZMikhail  
#20 Оставлено : 10 июня 2019 г. 20:39:34(UTC)
ZMikhail

Статус: Новичок

Группы: Участники
Зарегистрирован: 10.06.2019(UTC)
Сообщений: 2

Добрый день!
Столкнулся сейчас с точно такой же проблемой!
Подскажите, пжлст, каким образом удалось исключить элемент "Signature" в запросе XPath?
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
2 Страницы12>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.