При разработке механизмов выгрузки отчетности в контролирующие органы (ФНС, ФСС, Росстат) программисты часто сталкиваются с требованием предоставить файл с расширением .sgn. На первый взгляд может показаться, что это специфический формат сохранения табличного документа, аналогичный PDF или XLSX. Однако, проанализировав структуру таких файлов, мы увидим, что ситуация обстоит иначе. Разберемся, как правильно реализовать эту задачу в 1С.
Прежде чем приступать к написанию кода, проанализируем саму суть формата. Файл с расширением .sgn (а также .sig или .p7s) — это файл отсоединенной электронной подписи (detached signature). Он не содержит внутри себя текст документа или таблицу. В нем хранится криптографический отпечаток основного файла и данные сертификата электронной подписи.
Рассмотрим стандартную логику работы систем ФНС: они ожидают получить пару файлов. Первый — это сам документ в читаемом формате (например, XML, PDF или XLS), а второй — файл подписи с тем же именем, но расширением .sgn. Попытка «впихнуть» табличный документ напрямую в формат подписи технически невозможна, так как это разные сущности.
Для реализации требования заказчика «выгрузить документ в sgn» нам необходимо выполнить последовательность действий, которую мы разберем по шагам:
ТабличныйДокумент в памяти 1С.PDF)..sgn.Первым делом нам нужно преобразовать объект ТабличныйДокумент в физический файл. ФНС не принимает внутренний формат 1С (.mxl), поэтому используем PDF или XLSX. Рассмотрим пример кода:
// Определяем пути к файлам
ПутьКФайлуДокумента = "C:\Temp\Otchet.pdf";
ПутьКФайлуПодписи = "C:\Temp\Otchet.pdf.sgn";
// Сохраняем табличный документ в PDF
ТабДок.Записать(ПутьКФайлуДокумента, ТипФайлаТабличногоДокумента.PDF);
Для создания файла подписи нам потребуется объект МенеджерКриптографии. Важно понимать, что на компьютере, где выполняется этот код (на сервере или клиенте), должен быть установлен криптопровайдер (например, КриптоПро CSP) и соответствующий сертификат. Рассмотрим подробнее процесс формирования отсоединенной подписи:
// Инициализируем менеджер криптографии
// Параметры зависят от установленного криптопровайдера
Менеджер = Новый МенеджерКриптографии("", "", 75); // 75 - тип провайдера для КриптоПро
// Выбираем сертификат из хранилища (упрощенно)
Хранилище = Менеджер.ОткрытьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты,
РежимОткрытияХранилищаСертификатовКриптографии.ТолькоЧтение);
МассивСертификатов = Хранилище.НайтиПоОтпечатку(ОтпечатокСертификата);
Если МассивСертификатов.Количество() = 0 Тогда
Возврат; // Сертификат не найден
КонецЕсли;
Сертификат = МассивСертификатов[0];
// Подписываем файл
// Четвертый параметр "Истина" указывает на создание именно ОТСОЕДИНЕННОЙ подписи
Менеджер.Подписать(ПутьКФайлуДокумента, ПутьКФайлуПодписи, Сертификат, Истина);
В результате выполнения этого кода в папке C:\Temp\ появятся два файла. Файл Otchet.pdf.sgn и будет тем самым результатом, который требовал заказчик. Важно помнить, что метод Подписать объекта МенеджерКриптографии создает бинарный файл в кодировке DER, что полностью соответствует стандартам ФНС.
Если ваша конфигурация построена на базе современных типовых решений, мы настоятельно рекомендуем использовать механизмы БСП. Это позволит избежать низкоуровневой работы с криптопровайдерами и сделает код более универсальным. Посмотрим на пример использования общего модуля ЭлектроннаяПодпись:
// Подготовка данных для БСП
ДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлуДокумента);
ПараметрыПодписи = ЭлектроннаяПодпись.ПараметрыПодписания(Сертификат);
ПараметрыПодписи.ТипПодписи = Перечисления.ТипыПодписиКриптографии.CAdES_BES; // Или другой требуемый тип
// Получение подписи
РезультатПодписания = ЭлектроннаяПодпись.ПодписатьДанные(ДанныеФайла, ПараметрыПодписи);
Если РезультатПодписания.Выполнено Тогда
РезультатПодписания.ДанныеПодписи.Записать(ПутьКФайлуПодписи);
КонецЕсли;
Использование БСП предпочтительнее, так как библиотека берет на себя обработку ошибок, проверку сроков действия сертификатов и корректное взаимодействие с установленными на сервере модулями криптографии.
При реализации выгрузки следует обратить внимание на следующие моменты:
.p7s, для ФНС файл можно и нужно переименовывать в .sgn простым строковым методом или программным сохранением.Таким образом, задача «сохранить табличный документ в sgn» решается не через метод Записать() самого документа, а через дополнительный этап криптографической обработки сохраненного файла. Мы проанализировали ситуацию и выяснили, что ключ к решению — разделение процесса на генерацию контента и его подписание.