Как подписать строку с помощью сертификата криптографии в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интеграций со сторонними сервисами (например, МДЛП, Честный ЗНАК или различные государственные API) программисты 1С часто сталкиваются с необходимостью формирования цифровой подписи (ЭЦП). Нередко возникает задача подписать не готовый файл на диске, а динамически сформированную текстовую строку (например, JSON или XML).

Посмотрим на типичную ситуацию: мы уже получили нужный сертификат из хранилища, создали объект МенеджерКриптографии, но стандартные примеры часто показывают работу только с путями к файлам. Возникает вопрос: как передать обычную строку в метод Подписать? Разберем эту задачу по шагам и проанализируем различные способы решения.

Способ 1: Использование временных файлов (классический подход)

Исторически в 1С работа с криптографией часто была завязана на файловую систему. Этот подход заключается в том, что мы сохраняем нашу строку во временный файл, подписываем его стандартными методами, а затем считываем результат и удаляем временный файл. Для такой задачи можно использовать обработку для подписания произвольных файлов средствами платформы 1С.

Рассмотрим подробнее реализацию этого метода. Напишем функцию, которая принимает строку, сертификат и кодировку, а возвращает подписанные данные:


Функция ПодписатьСтрокуЧерезФайл(СтрокаДляПодписи, СертификатЭЦП, ТекстОшибки = "", Кодировка = "CESU-8") Экспорт
    ТекстОшибки = "";
    Результат = Неопределено;
    
    // Получаем путь к временному файлу
    ИмяВремФайла = ПолучитьИмяВременногоФайла();
    
    // Записываем строку в файл в нужной кодировке (например, CESU-8 или UTF-8)
    Текст = Новый ЗаписьТекста(ИмяВремФайла, Кодировка);
    Текст.Записать(СтрокаДляПодписи);
    Текст.Закрыть();
    
    // Инициализируем менеджер криптографии
    МенеджерКриптографии = Новый МенеджерКриптографии(СертификатЭЦП.ИмяПровайдера, "", СертификатЭЦП.КодПровайдера);
    
    // Получаем объект сертификата из двоичных данных
    Сертификат = Новый СертификатКриптографии(СертификатЭЦП.ФайлСертификата.Получить());
    
    Попытка
        // Метод Подписать принимает путь к файлу и сертификат
        Результат = МенеджерКриптографии.Подписать(ИмяВремФайла, Сертификат);
    Исключение
        ТекстОшибки = ОписаниеОшибки();
    КонецПопытки;
    
    // Обязательно удаляем временный файл
    Попытка
        УдалитьФайлы(ИмяВремФайла);
    Исключение
        // Игнорируем ошибку удаления или логируем
    КонецПопытки;
    
    Возврат Результат;
КонецФункции

Важное замечание: При записи текста обратите внимание на кодировку. В примере используется CESU-8 (это аналог UTF-8 без BOM). Если сервер, принимающий подписанные данные, ожидает строго определенную кодировку, несовпадение приведет к ошибке проверки подписи.

Способ 2: Современный подход (без записи на диск)

Работа с временными файлами имеет недостатки: это медленнее (из-за операций дискового ввода-вывода) и может вызывать ошибки прав доступа в серверных средах. Начиная с версии платформы 1С:Предприятие 8.3.9, метод Подписать умеет работать напрямую с объектом ДвоичныеДанные.

Проанализируем ситуацию: зачем писать на диск, если можно перевести строку в байты прямо в оперативной памяти? Рассмотрим, как это сделать правильно:


Функция ПодписатьСтрокуВПамяти(СтрокаДляПодписи, Сертификат, МенеджерКриптографии) Экспорт
    // 1. Конвертируем строку напрямую в двоичные данные. 
    // Ложь означает, что мы не добавляем BOM (Byte Order Mark).
    ДД = ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляПодписи, "UTF-8", Ложь);
    
    Попытка
        // 2. Передаем двоичные данные прямо в метод
        ДДПодписи = МенеджерКриптографии.Подписать(ДД, Сертификат);
        
        // 3. Обычно результат нужно передать в виде Base64 строки
        Возврат Base64Строка(ДДПодписи);
    Исключение
        Сообщить("Ошибка подписания: " + ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;
КонецФункции

Этот подход безопаснее, быстрее и избавляет от необходимости контролировать удаление временных файлов (мусора).

Важные нюансы при работе с электронной подписью

Рассмотрим дополнительные аспекты, которые критически важны для успешного формирования и проверки подписи на стороне получателя:

  1. Присоединенная и отсоединенная подпись: По умолчанию 1С формирует *присоединенную* подпись. Это значит, что итоговые двоичные данные содержат внутри себя и саму подпись, и исходный подписанный текст (стандарт CMS/PKCS#7). Если принимающее API (тот же Честный ЗНАК) требует *отсоединенную* подпись, необходимо в метод Подписать передать соответствующий параметр. Уточните требования к формату подписи в документации целевого сервиса.
  2. Явное указание алгоритмов: Разберем частую ошибку: вы подписали данные, но принимающая сторона сообщает о "неверном формате подписи". Проблема кроется в настройках по умолчанию. Всегда рекомендуется явно указывать свойства АлгоритмХеширования и АлгоритмПодписи при создании объекта МенеджерКриптографии, чтобы платформа использовала актуальный ГОСТ (например, ГОСТ Р 34.10-2012), а не устаревшие версии.
  3. Использование потоков: Если вы подписываете огромные XML файлы, преобразовывать их в единую строку и хранить в памяти нерационально. В таких случаях используйте объект ПотокВПамяти. Платформа 1С позволяет передавать потоки в криптографические методы.
  4. Библиотека стандартных подсистем (БСП): Если ваша конфигурация разработана на базе БСП (ERP, Бухгалтерия, ЗУП, УТ), настоятельно рекомендуем использовать готовый программный интерфейс — общий модуль ЭлектроннаяПодпись. Вызов ЭлектроннаяПодпись.Подписать() уже содержит внутри все необходимые проверки лицензий, сроков действия сертификатов, определение типа провайдера (Crypto-Pro или ViPNet) и обработку ошибок.

Посмотрим на итоги: для подписания строки в современных версиях платформы 1С лучше всего избегать временных файлов, напрямую конвертируя текст в объект ДвоичныеДанные. Обязательно обращайте внимание на кодировку (отсутствие BOM), формат подписи (отсоединенная или присоединенная) и используемые алгоритмы криптопровайдера.

← На главную