Внедрение электронной подписи (ЭП) в нетиповые конфигурации 1С часто вызывает вопросы у разработчиков, особенно когда речь идет о сложных интеграциях с системными криптопровайдерами, работой с сертификатами и обеспечением целостности данных путем блокировки документов. Рассмотрим, как шаг за шагом подойти к решению этих задач, используя как возможности Библиотеки стандартных подсистем (БСП), так и прямые механизмы платформы 1С.
Прежде чем погрузиться в детали, давайте проясним основные понятия. Электронная подпись — это информация в электронной форме, которая присоединена к другой информации в электронной форме или иным образом связана с такой информацией и которая используется для определения лица, подписывающего информацию. В контексте 1С это означает возможность подтвердить авторство и неизменность электронного документа или его части.
Платформа 1С:Предприятие 8.3 предоставляет встроенные механизмы для работы с криптографией через объект МенеджерКриптографии, который взаимодействует с криптопровайдерами, установленными в операционной системе (например, КриптоПро CSP, ViPNet CSP). Библиотека стандартных подсистем (БСП) значительно упрощает этот процесс, предоставляя готовые обертки и удобный интерфейс для типовых операций.
Мы будем стремиться к следующим минимальным требованиям, озвученным автором: установить отпечаток подписи в документ, заблокировать его от редактирования, а при отмене подписи — разблокировать. Также важна визуализация подписи на печатных формах, в том числе в PDF.
Если вы уже внедрили подсистему "Электронная подпись" из БСП, то львиная доля работы по взаимодействию с криптопровайдерами уже сделана. БСП предоставляет функции для поиска сертификатов, подписания данных и проверки подписей. В изучении доступных инструментов поможет справочник по методам БСП с примерами использования.
Разберем пример кода из сообщения 2, который демонстрирует процесс подписания и проверки:
Процедура КнопкаВыполнитьНажатие(Кнопка)
// 1. Получаем параметры CMS (Content Management System)
// Эти параметры часто содержат настройки алгоритмов, кодирования и т.д.
ПараметрыCMS = ЭлектроннаяПодпись.ПараметрыCMS;
// 2. Создаем менеджер криптографии для подписания
// "Подписание" - это вид операции, Ложь - не использовать интерактивное подтверждение
МенеджерКриптографии = ЭлектроннаяПодпись.МенеджерКриптографии("Подписание", Ложь);
// 3. Создаем менеджер криптографии для проверки подписи
МенеджерКриптографииДляПроверки = ЭлектроннаяПодпись.МенеджерКриптографии("ПроверкаПодписи", Ложь);
// 4. Устанавливаем пароль доступа к закрытому ключу, если он защищен паролем
// В реальных условиях пароль не должен быть жестко зашит в код.
// Обычно он запрашивается у пользователя или хранится в безопасном месте.
МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = "пароль";
// 5. Подписываем данные
// Функция Подписать - это обертка над ЭлектроннаяПодписьСлужебный.ПодписатьCMS
// Данные(БюджетнаяОперация) - конвертируем объект документа в двоичные данные для подписи
// ЭлектроннаяПодписьСлужебный.ПолучитьСертификатПоОтпечатку - получаем сертификат
// по его уникальному отпечатку (хешу).
РезультатПодписания = Подписать(
Данные(БюджетнаяОперация),
ПараметрыCMS,
ЭлектроннаяПодписьСлужебный.ПолучитьСертификатПоОтпечатку(СертификатыКлючейЭлектроннойПодписиИШифрования.Отпечаток, Истина, Ложь),
МенеджерКриптографии
);
// 6. Проверяем подпись
// РезультатПодписания.Подпись - это сама электронная подпись, которую мы только что создали
// Данные(БюджетнаяОперация) - те же данные, которые были подписаны
РезультатПроверки = ЭлектроннаяПодписьСлужебный.ПроверитьПодписьCMS(
РезультатПодписания.Подпись,
Данные(БюджетнаяОперация),
ПараметрыCMS,
МенеджерКриптографииДляПроверки
);
// Здесь можно обработать РезультатПодписания.Успех и РезультатПроверки
// Например, если РезультатПодписания.Успех = Истина, то сохраняем РезультатПодписания.Подпись
// в реквизит документа или в регистр сведений.
КонецПроцедуры
// Вспомогательная функция для подписания, показанная в сообщении 2
Функция Подписать(ДанныеДляПодписания, ПараметрыCMS, СертификатКриптографии, МенеджерКриптографии) Экспорт
ВозвращаемоеЗначение = Новый Структура;
ВозвращаемоеЗначение.Вставить("Успех");
ВозвращаемоеЗначение.Вставить("Подпись");
ВозвращаемоеЗначение.Вставить("ТекстОшибки");
Попытка
Подпись = ЭлектроннаяПодписьСлужебный.ПодписатьCMS(
ДанныеДляПодписания,
ПараметрыCMS,
СертификатКриптографии,
МенеджерКриптографии
);
ВозвращаемоеЗначение.Успех = Истина;
ВозвращаемоеЗначение.Подпись = Подпись;
Исключение
ВозвращаемоеЗначение.Успех = Ложь;
ВозвращаемоеЗначение.ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецПопытки;
Возврат ВозвращаемоеЗначение;
КонецФункции
Как мы видим, БСП инкапсулирует сложность работы с криптографическими примитивами. Подобные механизмы позволяют реализовать универсальную выгрузку и загрузку данных с шифрованием. Ключевые моменты:
ЭлектроннаяПодпись.ПараметрыCMS: Это объект, который содержит настройки для формирования подписи (алгоритмы хеширования, шифрования, формат подписи и т.д.). В большинстве случаев его можно использовать по умолчанию.ЭлектроннаяПодпись.МенеджерКриптографии("Подписание", Ложь): Создает экземпляр менеджера криптографии, настроенный для выполнения операции подписания. Второй параметр Ложь указывает, что не требуется интерактивное взаимодействие с пользователем (например, запрос PIN-кода через диалоговое окно криптопровайдера) на этом этапе.Данные(БюджетнаяОперация): Очень важный шаг. Для подписания любого объекта 1С (документа, справочника, произвольных данных) необходимо преобразовать его в двоичный формат. Функция Данные() выполняет эту задачу. Подписывается именно это двоичное представление.ЭлектроннаяПодписьСлужебный.ПолучитьСертификатПоОтпечатку(...): Эта служебная функция БСП позволяет найти установленный сертификат по его уникальному отпечатку (хешу). Отпечаток обычно хранится в реквизите документа или регистре сведений, связанном с подписью.ЭлектроннаяПодписьСлужебный.ПодписатьCMS(...) и ЭлектроннаяПодписьСлужебный.ПроверитьПодписьCMS(...): Это основные функции БСП для выполнения криптографических операций. Они используют созданный ранее МенеджерКриптографии для взаимодействия с установленным криптопровайдером.После успешного подписания, полученная структура подписи (РезультатПодписания.Подпись) должна быть сохранена в базе данных. Поскольку криптографические операции могут быть длительными, рекомендуется использовать механизмы длительных операций в БСП для улучшения пользовательского интерфейса.
Автор столкнулся с проблемой попытки чтения реестра Windows для получения списка установленных криптопровайдеров, используя функции RegRead и EnumKey. Важно понимать, что встроенные функции 1С:Предприятия для работы с реестром (например, глобальная функция РегПрочитать(), или COM-объекты вроде WScript.Shell) имеют ограничения. РегПрочитать() позволяет получить значение конкретного параметра реестра по полному пути, но не предоставляет функционал для перечисления подразделов или значений в ключе. Объект WScript.Shell также в основном ограничен простыми операциями чтения/записи значений, но не поддерживает метод EnumKey или его аналоги для полного перечисления дочерних ключей, как это возможно в полноценных языках программирования или с помощью специализированных API.
Таким образом, напрямую из встроенного языка 1С получить полный список *всех* установленных криптопровайдеров операционной системы без использования внешних компонент или сторонних средств практически невозможно. Застрять на RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider") и получить пустое значение – это ожидаемый результат, поскольку этот путь указывает на раздел, а не на конкретное значение, а EnumKey действительно не является методом, доступным в 1С для этой цели.
Вместо попыток прямого чтения реестра, в 1С принято использовать следующие подходы:
МенеджерКриптографии в блок Попытка...Исключение и предоставляйте пользователю информативное сообщение. Например:
Попытка
// Попытка получить сертификат, который требует определенного криптопровайдера
Сертификат = ЭлектроннаяПодписьСлужебный.ПолучитьСертификатПоОтпечатку(Отпечаток, Истина, Ложь);
// ... далее код подписания ...
Исключение
Сообщить("Ошибка при работе с электронной подписью. Возможно, не установлен необходимый криптопровайдер ('КриптоПро CSP' или 'ViPNet CSP') или сертификат.", СтатусСообщения.Важное);
Возврат;
КонецПопытки;
Для определения, какой криптопровайдер необходим для конкретного сертификата, посмотрите свойства сертификата в оснастке Windows (сертификаты текущего пользователя) на вкладке "Состав" – поле "Средство электронной подписи". Там будет указано его название (например, "КриптоПРО CSP" или "ViPNet CSP").
Важное замечание: Одновременная установка "КриптоПро CSP" и "ViPNet CSP" на одном компьютере не рекомендуется. Это часть общей концепции защищенной IT-инфраструктуры, которую необходимо учитывать при внедрении ЭП. Выбирайте один продукт в соответствии с требованиями удостоверяющего центра.
После установки сертификатов в хранилище Windows (обычно через панель управления криптопровайдера), 1С может их "найти". БСП предоставляет удобные механизмы для этого:
ЭлектроннаяПодписьСлужебный.ПолучитьСертификатПоОтпечатку(Отпечаток, Истина, Ложь) позволяет получить конкретный сертификат, если вы знаете его отпечаток. Это наиболее часто используемый способ, так как отпечаток является уникальным идентификатором сертификата.При использовании ЭлектроннаяПодписьСлужебный.ПолучитьСертификатПоОтпечатку, если сертификат не найден или криптопровайдер, с которым он связан, отсутствует, функция выдаст ошибку. Это можно использовать для определения доступности сертификата и криптопровайдера.
Требования автора к блокировке документов после подписания и разблокировке при отмене подписи являются фундаментальными для обеспечения целостности и юридической значимости электронных документов. Если документ подписан, его содержимое считается зафиксированным и неизменным.
Мы реализуем эту логику с помощью специального реквизита и программного контроля:
Для начала, добавьте в ваш документ новый реквизит булевого типа, например, ПодписанЭП, а также реквизит для хранения самой подписи (типа "ХранилищеЗначения", например, ДанныеЭлектроннойПодписи).
ДанныеЭлектроннойПодписи, установите реквизит Объект.ПодписанЭП = Истина и запишите документ.ПриСозданииНаСервере или ПриЧтенииНаСервере, проверяйте значение реквизита ПодписанЭП. Если документ подписан, мы делаем его доступным только для просмотра:
// В обработчике ПриСозданииНаСервере или ПриЧтенииНаСервере формы документа
Если Объект.ПодписанЭП Тогда
// Устанавливаем режим просмотра для всей формы
ЭтаФорма.ТолькоПросмотр = Истина;
// Если нужно сделать доступными некоторые элементы (например, для просмотра самой подписи)
// Элементы.ГруппаСПодписью.ТолькоПросмотр = Ложь;
КонецЕсли;
Установка ЭтаФорма.ТолькоПросмотр = Истина; является самым простым способом заблокировать редактирование всех элементов формы. Если необходимо выборочно блокировать элементы, придется пройтись по нужным элементам и установить их свойство Доступность = Ложь; или ТолькоПросмотр = Истина;.
ПередЗаписьюНаСервере:
// В обработчике ПередЗаписьюНаСервере
// Проверяем, что документ подписан
Если Объект.ПодписанЭП Тогда
// Проверяем, были ли изменены основные данные документа
// Здесь важно не путать с изменением служебных реквизитов, таких как сама подпись.
// Если подпись хранится в основном документе, а мы ее только что записали,
// то документ будет считаться модифицированным.
// Более надежно - проверять изменения только ключевых реквизитов.
// Если подпись хранится в отдельном регистре, то Модифицированность() объекта
// будет корректно показывать, если изменились другие данные.
// Если подпись в реквизите объекта, потребуется сравнение с сохраненной версией объекта.
Если Модифицированность Тогда
// Перед отказом можно выполнить дополнительные проверки,
// чтобы убедиться, что изменены именно содержательные данные, а не служебные.
// Например, можно сравнить текущую версию объекта с версией из базы данных.
Отказ = Истина;
Сообщить("Документ подписан электронной подписью и не может быть изменен.");
Возврат;
КонецЕсли;
КонецЕсли;
Особенности Модифицированность(): Метод Модифицированность() формы проверяет, были ли изменены данные формы с момента ее открытия или последней записи. Если реквизит ДанныеЭлектроннойПодписи или ПодписанЭП находится в том же объекте документа, и вы его изменяете, то форма будет считаться модифицированной. Для точной блокировки редактирования *содержания* документа, может потребоваться сохранять подпись в отдельном, связанном регистре сведений. В этом случае, изменение регистра не будет влиять на Модифицированность() самого документа, и проверка будет работать более предсказуемо.
Если предусмотрена функциональность "отмены" или "аннулирования" подписи (что требует отдельной процедуры и, возможно, новой подписи об аннулировании), то в этой процедуре вы должны установить Объект.ПодписанЭП = Ложь и записать документ. После этого, при следующем открытии документа, форма не будет установлена в режим "ТолькоПросмотр" и документ станет доступен для редактирования. Важно, чтобы при отмене подписи также удалялись или помечались как неактуальные данные самой подписи.
В типовых конфигурациях 1С существует механизм "Дата запрета изменения". Хотя он обычно используется для запрета изменения данных за определенный период (например, после закрытия месяца), его можно адаптировать. Например, при подписании документа можно устанавливать "дату запрета" для данного документа, равную дате подписи. Однако это более громоздкий способ и не так гибок, как программная блокировка отдельных документов.
Для подписанных документов настоятельно рекомендуется включить версионирование объектов. Это позволит всегда иметь доступ к той версии документа, которая была подписана, даже если документ был впоследствии изменен (что крайне нежелательно для подписанных документов) или подпись была аннулирована.
Важный аспект: Если подписание происходит на сервере (например, через регламентное задание или при автоматической обработке), то криптопровайдер и сертификаты должны быть установлены на сервере под учетной записью пользователя, от имени которого работает служба "Агент сервера 1С:Предприятия". В этом случае на клиентских машинах установка криптопровайдера не требуется, что упрощает развертывание.
Визуализация штампа электронной подписи на печатных формах или в PDF-документах является важным элементом удобства и доверия. Она позволяет пользователям быстро увидеть факт наличия ЭП и основные данные о ней (кто подписал, когда).
Для реализации штампа рассмотрим следующие подходы:
Если печатная форма генерируется непосредственно в 1С (например, в формате табличного документа 1С или с выгрузкой в Word/Excel), вы можете добавить область для штампа. При подписании документа, информация о подписи (ФИО подписанта, дата, отпечаток) сохраняется. При формировании печатной формы, если документ подписан, мы вставляем эту информацию в специальную область шаблона.
// Пример добавления текста штампа в табличный документ 1С
ОбластьМакета = Макет.ПолучитьОбласть("ОбластьШтампа");
ОбластьМакета.Параметры.Подписант = "Иванов И.И. (ЭЦП)";
ОбластьМакета.Параметры.ДатаПодписи = Формат(ТекущаяДата(), "ДЛФ=ДВ");
// Можно добавить QR-код с ссылкой на проверку подписи или с самим отпечатком
// (требует предварительной генерации картинки QR-кода)
// ОбластьМакета.Рисунки.Вставить(ИмяКартинкиQR, ИмяОбласти, Лево, Верх, Ширина, Высота);
ТабДокумент.Вывести(ОбластьМакета);
Добавление штампа в PDF-файл сложнее, поскольку PDF — это бинарный формат, и для его программного изменения требуются специальные библиотеки или сервисы.
В любом случае, при создании штампа в PDF, убедитесь, что он не перекрывает важную информацию документа и что его расположение является консистентным. Возможность проверки подписи по QR-коду значительно повышает удобство.
Хотя БСП значительно упрощает работу с ЭП, существуют сценарии, когда ее использование может быть избыточным или невозможным. В таких случаях можно рассмотреть прямую работу с МенеджерКриптографии или использование других средств.
МенеджерКриптографии:
Объект МенеджерКриптографии платформы 1С предоставляет низкоуровневые методы для криптографических операций: Подписать(), Проверить(), Зашифровать(), Расшифровать(), ПолучитьХеш(). Вам потребуется более детально управлять параметрами криптопровайдера (его имя и тип), алгоритмами и процессом выбора сертификата.
МенеджерКриптографии = Новый МенеджерКриптографии;
// Указываем параметры криптопровайдера, например, для КриптоПро CSP GOST R 34.10-2012
// ИмяПрограммы = "Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider";
// ТипМодуля = 80; // Соответствует типу CSP_PROV_GOST_2012_256 для КриптоПро
// МенеджерКриптографии.УстановитьПараметрыПрограммы(ИмяПрограммы, ТипМодуля);
// Получение сертификата: можно использовать МенеджерКриптографии.ПолучитьСертификаты()
// и выбрать нужный из списка или по отпечатку.
// Сертификат = МенеджерКриптографии.ПолучитьСертификатИзХранилища(...);
// Затем можно вызывать методы:
// Подпись = МенеджерКриптографии.Подписать(ДанныеДляПодписания, Сертификат, ...);
Этот подход требует более глубокого понимания CryptoAPI и специфики криптопровайдеров, но дает полный контроль над процессом.
Как упоминалось в сообщении 3, OpenSSL — это мощная криптографическая библиотека. Однако в контексте юридически значимой электронной подписи в РФ требуется использование сертифицированных средств криптографической защиты информации (СКЗИ), поддерживающих ГОСТ-алгоритмы (КриптоПро CSP, ViPNet CSP). OpenSSL по умолчанию не поддерживает ГОСТ-алгоритмы (хотя есть модификации). Использовать OpenSSL для формирования юридически значимой ЭП в 1С без специализированных внешних компонент или интеграции с CryptoAPI/СКЗИ может быть сложно и не соответствовать российскому законодательству. Его чаще применяют для обеспечения защищенных соединений (HTTPS) или работы с самоподписанными сертификатами в специфических сценариях (например, в мобильной платформе 1С).
Реализация электронной подписи в нетиповой конфигурации 1С, особенно с учетом необходимости работы с криптопровайдерами, сертификатами, блокировкой документов и визуализацией штампов, является комплексной задачей. Использование Библиотеки стандартных подсистем (БСП) – это наиболее рекомендуемый и эффективный путь, поскольку она предоставляет готовые, отлаженные и поддерживаемые механизмы. Однако, понимание базовых принципов работы с МенеджерКриптографии и системными криптопровайдерами остается критически важным для диагностики и тонкой настройки. Всегда учитывайте требования законодательства РФ к электронной подписи, которые диктуют использование сертифицированных СКЗИ.