Как отправить клиентский сертификат через HTTPСоединение в 1С 8.1?

Программист IT и автоматизация бизнеса
← На главную

При работе на платформе 1С:Предприятие 8.1 программисты часто сталкиваются с существенными ограничениями встроенного объекта HTTPСоединение. Одной из наиболее острых проблем является реализация защищенного соединения (HTTPS) с использованием клиентских сертификатов. В современных версиях платформы (8.3.x) для этого предусмотрены специализированные объекты вроде ЗащищенноеСоединениеOpenSSL, однако в версии 8.1 функционал крайне ограничен. Рассмотрим, почему стандартные методы не работают и как решить эту задачу с помощью внешних инструментов.

Анализ проблемы штатного объекта HTTPСоединение

В платформе 8.1 конструктор объекта HTTPСоединение принимает параметр ЗащищенноеСоединение, который может принимать лишь логическое значение Истина или Ложь. Мы не можем явно указать, какой сертификат использовать, или настроить параметры TLS. Платформа в данном случае полностью полагается на настройки операционной системы и системное хранилище сертификатов Windows.

Проанализируем типичную ситуацию: при попытке инициализировать соединение с параметром ЗащищенноеСоединение = Истина, система может аварийно завершить работу или выдать неинформативную ошибку, которую даже не всегда удается перехватить блоком Попытка ... Исключение. Это происходит из-за того, что механизм WinInet, используемый в 8.1, пытается автоматически подобрать сертификат из личного хранилища текущего пользователя. Если сертификатов несколько, требуется ввод пароля или сервер требует специфический протокол (например, TLS 1.2), штатный объект просто «сдается».

Решение через использование COM-объекта WinHttp

Наиболее надежным и проверенным способом решения данной задачи в 1С 8.1 является использование системного COM-объекта WinHttp.WinHttpRequest.5.1. Этот объект предоставляет гораздо больше контроля над процессом передачи данных, включая возможность явного указания клиентского сертификата и настройки параметров безопасности. Разберем по шагам реализацию этого метода.

Рассмотрим пример кода, который позволяет отправить запрос с использованием конкретного сертификата:


Процедура ЗапросКСервисуНаПлатформе1С8_1(Сервер, Сервис, СертификатИмя, ТипЗапроса, ТекстЗапроса)
    // Создаем основной объект для выполнения HTTP-запросов
    WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
    
    // Настраиваем использование кодировки UTF-8 для корректной передачи данных
    WinHttp.Option(2, "UTF-8");
    
    // Указываем имя сертификата, который должен быть предварительно установлен 
    // в хранилище сертификатов Windows
    WinHttp.SetClientCertificate(СертификатИмя);
    
    // Устанавливаем тайм-ауты (разрешение имен, соединение, отправка, получение)
    WinHttp.SetTimeouts(10000, 10000, 30000, 30000);
    
    // В некоторых случаях для корректной работы с кодировками и специфическими флагами 
    // удобно использовать MSScriptControl
    Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
    Скрипт.Language = "javascript";
    Скрипт.AddObject("WinHttp", WinHttp);
    
    // Принудительно устанавливаем опции через скрипт
    Скрипт.Eval("WinHttp.Option(2) = ""utf-8"""); // Кодировка
    Скрипт.Eval("WinHttp.Option(4) = 13056");    // Игнорирование ошибок сертификатов (если нужно)
    Скрипт.Eval("WinHttp.Option(6) = true");     // Разрешить редиректы
    Скрипт.Eval("WinHttp.Option(12) = true");    // Использовать современные протоколы безопасности
    
    // Открываем соединение (ТипЗапроса: "GET", "POST", "PUT" и т.д.)
    WinHttp.Open(ТипЗапроса, Сервер + Сервис, 0);
    
    // Устанавливаем заголовки, если работаем с JSON
    WinHttp.SetRequestHeader("Content-Type", "application/json;charset=UTF-8");
    
    // Отправляем тело запроса
    WinHttp.Send(ТекстЗапроса);
    
    // Получаем ответ сервера
    Ответ = WinHttp.ResponseText;
    Сообщить(Ответ);
КонецПроцедуры

Разбор ключевых настроек WinHttp

Выясним причину использования дополнительных флагов Option. В 1С 8.1 работа с типами данных в COM-объектах иногда может приводить к ошибкам, поэтому использование MSScriptControl позволяет гарантированно передать нужные числовые значения флагов.

Важные опции WinHttp:

  1. Option(4) — SslErrorIgnoreFlags: Значение 13056 позволяет игнорировать распространенные ошибки SSL, такие как несовпадение имени хоста или самоподписанный сертификат. Это полезно при работе с тестовыми стендами.
  2. Option(9) — SecureProtocols: Хотя в примере выше он не указан явно, это критически важный параметр. Платформа 8.1 по умолчанию может пытаться использовать SSL 3.0. Чтобы задействовать TLS 1.2, необходимо установить значение 2048.
  3. Метод SetClientCertificate: В качестве параметра принимает строку, идентифицирующую сертификат. Это может быть заголовок (Subject) сертификата или путь к нему в хранилище.

Особенности работы на стороне сервера

Проанализируем ситуацию, когда код выполняется в контексте сервера 1С. Это важный момент, так как объект WinHttp будет обращаться к хранилищу сертификатов того пользователя, под которым запущена служба 1С (например, USR1CV81). Если вы установили сертификат под своей учетной записью администратора («Текущий пользователь»), серверная часть 1С его просто не увидит.

Для стабильной работы рекомендуется:

Формирование JSON в 1С 8.1

Посмотрим на пример формирования заголовков. В сообщениях форума упоминалось, что строка Заголовки.Вставить("Content-Type", "application/json;charset=UTF-8") может вызывать ошибку. В 8.1 объект Соответствие работает корректно, но стоит помнить, что сама платформа не имеет встроенных функций ПрочитатьJSON или ЗаписатьJSON. Вам придется формировать тело запроса вручную, объединяя строки, и крайне внимательно следить за кодировкой. Используйте WinHttp.Send() с корректно подготовленной строкой, предварительно убедившись, что сервер ожидает именно такой формат данных.

Альтернативные варианты

Если работа с WinHttp кажется слишком сложной или сертификаты требуют специфического взаимодействия (например, аппаратные ключи), рассмотрим альтернативные пути:

  1. Переход на режим совместимости: Если есть возможность, обновите платформу до 8.3, сохранив режим совместимости с 8.1. Это позволит использовать современные объекты HTTPЗапрос и ЗащищенноеСоединениеOpenSSL.
  2. Использование прокси (stunnel): Можно настроить локальную утилиту stunnel, которая будет принимать обычные HTTP-запросы от 1С на локальный порт, «оборачивать» их в TLS с нужным сертификатом и переправлять на целевой сервер. Для 1С это будет выглядеть как простейшее незащищенное соединение.

Таким образом, несмотря на почтенный возраст платформы 8.1, задача передачи клиентских сертификатов решаема. Использование WinHttp.WinHttpRequest.5.1 является наиболее гибким и мощным инструментом, позволяющим обойти архитектурные ограничения старых версий 1С.

← На главную