В практике разработки на платформе 1С часто возникает задача обеспечить юридическую значимость или неизменность данных не только для присоединенных файлов, но и для обычных записей в регистрах сведений. Это необходимо для фиксации управленческих решений, подтверждения ознакомления с документами или защиты данных от корректировок "задним числом". Разберем подробно, как реализовать этот механизм, начиная с подготовки данных и заканчивая выводом визуального штампа в отчет.
Прежде всего, проанализируем ситуацию: в отличие от файла, который представляет собой фиксированную последовательность байтов, запись регистра — это логическая структура. Мы не можем "подписать" саму строку в SQL-таблице напрямую средствами криптографии. Чтобы решить эту задачу, нам необходимо преобразовать набор реквизитов записи в стабильный двоичный поток, который и будет подписан.
Рассмотрим первый и самый важный этап — сериализацию. Чтобы подпись была валидной при проверке спустя время, данные должны всегда преобразовываться в абсолютно идентичную последовательность байтов. Малейшее изменение (лишний пробел, другой порядок полей в XML или JSON) приведет к тому, что хеш данных изменится, и подпись станет неверной.
Для этого рекомендуем использовать канонизацию данных. Мы должны строго определить набор подписываемых полей (измерения, ресурсы, реквизиты) и алгоритм их сборки в строку. Посмотрим на пример формирования структуры данных для подписи:
Функция СформироватьДанныеДляПодписи(ЗаписьРегистра) Экспорт
// Используем структуру для фиксации набора данных
Данные = Новый Структура;
Данные.Вставить("Период", Формат(ЗаписьРегистра.Период, "ДФ=yyyyMMddHHmmss"));
Данные.Вставить("Сотрудник_ФИО", ЗаписьРегистра.Сотрудник.Наименование);
Данные.Вставить("Сотрудник_ИНН", ЗаписьРегистра.Сотрудник.ИНН);
Данные.Вставить("Сумма", Формат(ЗаписьРегистра.Сумма, "ЧЦ=15; ЧДЦ=2; ЧГ=0"));
// Сериализуем в JSON с фиксированным порядком ключей
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(,,, ЭлементыСоставаОбъектаJSON.ИмяСвойства);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, Данные);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
Важный нюанс: никогда не подписывайте только GUID (ссылку) справочника. Если вы подпишете GUID сотрудника, а затем в справочнике изменят его ФИО, подпись под записью регистра формально останется верной, но смысл данных изменится. Всегда включайте в подписываемую строку значимые текстовые представления объектов ("снимок данных").
Выясним, как технически установить подпись. В современных конфигурациях нет необходимости писать низкоуровневый код взаимодействия с криптопровайдером (КриптоПро, VipNet). Лучше всего использовать возможности Библиотеки стандартных подсистем (БСП), а именно подсистему ЭлектроннаяПодпись.
Для реализации задачи нам подойдет формат отсоединенной подписи (Detached Signature). В этом случае сами данные записи остаются доступными для чтения и отчетов в обычном виде, а файл подписи (обычно в формате .p7s) хранится в отдельном хранилище или реквизите типа ХранилищеЗначения.
Для формирования подписи используйте методы программного интерфейса БСП, такие как ЭлектроннаяПодпись.Подписать(). Это позволит системе автоматически вызвать окно выбора сертификата и выполнить криптографическую операцию.
Проанализируем ситуацию с хранением. Чтобы база не "разбухала" от дублирования данных в XML, мы рекомендуем хранить только сам файл подписи. Однако возникает риск: что если пользователь изменит реквизиты записи в регистре, а подпись останется старой? Для предотвращения этого необходимо внедрить два механизма защиты:
ПередЗаписью регистра сведений необходимо проверять, установлена ли для этой записи подпись. Если установлена — вызываем Отказ = Истина.Рассмотрим, как вывести красивый штамп "Подписано ЭЦП" в печатную форму или отчет. Для этого не нужно каждый раз обращаться к криптоядру, так как это замедлит формирование отчета. Правильным подходом будет кеширование данных сертификата в момент подписания.
Добавьте в регистр (или связанную таблицу) текстовые реквизиты: Подписант, СерийныйНомерСертификата, ДатаПодписи, СрокДействияДо. При успешном наложении подписи извлеките эти данные из объекта СертификатКриптографии и сохраните их.
В макете отчета создайте область "Штамп", которая будет содержать:
Разберем важный методологический момент. Обычная электронная подпись может перестать проходить проверку, как только истечет срок действия сертификата подписанта (обычно через 1 год). Если вам нужно, чтобы отчет со штампом был валиден через 3 или 5 лет, необходимо использовать усовершенствованные форматы подписи, например CAdES-X Long. Этот формат включает в себя метку времени и доказательства того, что сертификат не был отозван на момент подписания. Это требует настройки службы штампов времени (TSP) в вашей организации.
Подводя итог, алгоритм реализации выглядит так:
ЗаписьJSON).БСП для формирования отсоединенной подписи.Такой подход обеспечивает баланс между производительностью системы (отчеты формируются быстро) и юридической достоверностью данных.