При разработке интеграций со сторонними сервисами (например, МДЛП, Честный ЗНАК или различные государственные API) программисты 1С часто сталкиваются с необходимостью формирования цифровой подписи (ЭЦП). Нередко возникает задача подписать не готовый файл на диске, а динамически сформированную текстовую строку (например, JSON или XML).
Посмотрим на типичную ситуацию: мы уже получили нужный сертификат из хранилища, создали объект МенеджерКриптографии, но стандартные примеры часто показывают работу только с путями к файлам. Возникает вопрос: как передать обычную строку в метод Подписать? Разберем эту задачу по шагам и проанализируем различные способы решения.
Исторически в 1С работа с криптографией часто была завязана на файловую систему. Этот подход заключается в том, что мы сохраняем нашу строку во временный файл, подписываем его стандартными методами, а затем считываем результат и удаляем временный файл. Для такой задачи можно использовать обработку для подписания произвольных файлов средствами платформы 1С.
Рассмотрим подробнее реализацию этого метода. Напишем функцию, которая принимает строку, сертификат и кодировку, а возвращает подписанные данные:
Функция ПодписатьСтрокуЧерезФайл(СтрокаДляПодписи, СертификатЭЦП, ТекстОшибки = "", Кодировка = "CESU-8") Экспорт
ТекстОшибки = "";
Результат = Неопределено;
// Получаем путь к временному файлу
ИмяВремФайла = ПолучитьИмяВременногоФайла();
// Записываем строку в файл в нужной кодировке (например, CESU-8 или UTF-8)
Текст = Новый ЗаписьТекста(ИмяВремФайла, Кодировка);
Текст.Записать(СтрокаДляПодписи);
Текст.Закрыть();
// Инициализируем менеджер криптографии
МенеджерКриптографии = Новый МенеджерКриптографии(СертификатЭЦП.ИмяПровайдера, "", СертификатЭЦП.КодПровайдера);
// Получаем объект сертификата из двоичных данных
Сертификат = Новый СертификатКриптографии(СертификатЭЦП.ФайлСертификата.Получить());
Попытка
// Метод Подписать принимает путь к файлу и сертификат
Результат = МенеджерКриптографии.Подписать(ИмяВремФайла, Сертификат);
Исключение
ТекстОшибки = ОписаниеОшибки();
КонецПопытки;
// Обязательно удаляем временный файл
Попытка
УдалитьФайлы(ИмяВремФайла);
Исключение
// Игнорируем ошибку удаления или логируем
КонецПопытки;
Возврат Результат;
КонецФункции
Важное замечание: При записи текста обратите внимание на кодировку. В примере используется CESU-8 (это аналог UTF-8 без BOM). Если сервер, принимающий подписанные данные, ожидает строго определенную кодировку, несовпадение приведет к ошибке проверки подписи.
Работа с временными файлами имеет недостатки: это медленнее (из-за операций дискового ввода-вывода) и может вызывать ошибки прав доступа в серверных средах. Начиная с версии платформы 1С:Предприятие 8.3.9, метод Подписать умеет работать напрямую с объектом ДвоичныеДанные.
Проанализируем ситуацию: зачем писать на диск, если можно перевести строку в байты прямо в оперативной памяти? Рассмотрим, как это сделать правильно:
Функция ПодписатьСтрокуВПамяти(СтрокаДляПодписи, Сертификат, МенеджерКриптографии) Экспорт
// 1. Конвертируем строку напрямую в двоичные данные.
// Ложь означает, что мы не добавляем BOM (Byte Order Mark).
ДД = ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляПодписи, "UTF-8", Ложь);
Попытка
// 2. Передаем двоичные данные прямо в метод
ДДПодписи = МенеджерКриптографии.Подписать(ДД, Сертификат);
// 3. Обычно результат нужно передать в виде Base64 строки
Возврат Base64Строка(ДДПодписи);
Исключение
Сообщить("Ошибка подписания: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
Этот подход безопаснее, быстрее и избавляет от необходимости контролировать удаление временных файлов (мусора).
Рассмотрим дополнительные аспекты, которые критически важны для успешного формирования и проверки подписи на стороне получателя:
Подписать передать соответствующий параметр. Уточните требования к формату подписи в документации целевого сервиса.АлгоритмХеширования и АлгоритмПодписи при создании объекта МенеджерКриптографии, чтобы платформа использовала актуальный ГОСТ (например, ГОСТ Р 34.10-2012), а не устаревшие версии.ПотокВПамяти. Платформа 1С позволяет передавать потоки в криптографические методы.ЭлектроннаяПодпись. Вызов ЭлектроннаяПодпись.Подписать() уже содержит внутри все необходимые проверки лицензий, сроков действия сертификатов, определение типа провайдера (Crypto-Pro или ViPNet) и обработку ошибок.Посмотрим на итоги: для подписания строки в современных версиях платформы 1С лучше всего избегать временных файлов, напрямую конвертируя текст в объект ДвоичныеДанные. Обязательно обращайте внимание на кодировку (отсутствие BOM), формат подписи (отсоединенная или присоединенная) и используемые алгоритмы криптопровайдера.