Работа с API ЭДО Лайт в системе «Честный ЗНАК» часто сопровождается трудностями при выполнении процедуры подписания исходящих документов. Одной из самых распространенных проблем, с которой сталкиваются разработчики при интеграции 1С, является ошибка «Ошибка подписи» при попытке подтвердить ранее созданный черновик. Давайте разберем, почему это происходит и как правильно реализовать этот процесс, чтобы избежать искажения данных.
Основная проблема при работе с API через 1С заключается в неявном преобразовании типов данных. Многие разработчики пытаются получать содержимое XML-файла и передавать подпись, конвертируя данные в строки (например, используя кодировки windows-1251 или UTF-8). Однако в процессе такой конвертации происходят изменения байтового представления документа, которые нарушают целостность подписи. В результате сервер ГИС МТ получает данные, которые не соответствуют контрольной сумме исходного черновика.
Золотое правило интеграции с ЭДО Лайт: отказывайтесь от любых преобразований в строковые форматы. Работайте исключительно с ДвоичныеДанные на всех этапах: от получения контента черновика до отправки сформированного пакета подписи.
Чтобы избежать перекодировок, необходимо использовать методы HTTPОтвет.ПолучитьТелоКакДвоичныеДанные() для получения файла и HTTPЗапрос.УстановитьТелоИзДвоичныхДанных() для его отправки. Рассмотрим пример корректной функции отправки подписи:
Функция ПодписатьИОтправитьДокументВЭДОЛайт(ВыбранныйСертификат, Токен, ИД_ЭДО) Экспорт
Результат = Новый Структура("Выполнено,ТекстОшибки", Ложь, "");
// Получаем контент документа как двоичные данные
HTTPСоединение = Новый HTTPСоединение(ПолучитьАдресГИС_МТ, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
URLЗапроса = СтрШаблон("/api/v1/outgoing-documents/%1/content", ИД_ЭДО);
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
HTTPОтвет = HTTPСоединение.ВызватьHTTPМетод("GET", HTTPЗапрос);
ДВXMLДокумент = HTTPОтвет.ПолучитьТелоКакДвоичныеДанные();
// Подписываем (используя присоединенную или открепленную подпись в зависимости от требований метода)
ПодписанныйДокументБинар = ПодписатьСертификатомДвоичныеДанные(ВыбранныйСертификат, ДВXMLДокумент);
// Отправляем результат
URLЗапроса = СтрШаблон("/api/v1/outgoing-documents/%1/signature", ИД_ЭДО);
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса);
HTTPЗапрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ПодписанныйДокументБинар);
HTTPОтвет = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
// Обработка ответа...
КонецФункции
Если метод последовательного подписания черновика вызывает ошибки, рекомендуется использовать передачу данных и подписи одним пакетом через multipart/form-data. Это позволяет серверу гарантированно связать файл и его электронную подпись в рамках одной транзакции.
При использовании этого подхода мы самостоятельно формируем тело запроса, используя разделитель (boundary). Важно правильно указать Content-Type с параметром boundary.
// Пример формирования multipart-запроса
Р = "---------------------------Boundary_String_12345";
Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Р);
Тело = "--" + Р + Символы.ПС +
"Content-Disposition: form-data; name=""content""; filename=""doc.xml""" + Символы.ПС +
"Content-Type: application/xml" + Символы.ПС + Символы.ПС +
ДанныеФайла + Символы.ПС +
"--" + Р + Символы.ПС +
"Content-Disposition: form-data; name=""signature""" + Символы.ПС +
"Content-Type: text/plain" + Символы.ПС + Символы.ПС +
Base64Строка(Подпись) + Символы.ПС +
"--" + Р + "--";
ПолучитьТелоКакСтроку("windows-1251") при работе с контентом API. Получайте данные только в бинарном виде.GET /api/v1/outgoing-documents/%1/content.CAdESCOM.CPSigner, встроенные в компоненты КриптоПро, обеспечивая корректное формирование присоединенной или открепленной подписи согласно спецификации вашего метода API.Следуя этим рекомендациям и исключив строковые преобразования из своего кода, вы сможете добиться стабильной работы с API ЭДО Лайт и избавиться от ошибок подписи навсегда.