При попытке вызова защищенного веб-сервиса через встроенные механизмы платформы 1С:Предприятие 8.1 разработчики часто сталкиваются с ошибкой: Ошибка работы с Интернет: problem with the SSL CA cert (path? access rights?). Разберем причины возникновения этой ошибки и рассмотрим практические способы организации взаимодействия с современными защищенными сервисами.
Проанализируем техническую сторону проблемы. В платформе 8.1 сетевые вызовы опираются на встроенные устаревшие версии библиотек libcurl и OpenSSL. Ошибка с кодом 77 сообщает о том, что платформа не может прочитать файл сертификатов удостоверяющего центра или проверить цепочку доверия. Кроме того, в платформе 8.1 отсутствуют современные объекты управления защищенным соединением (такие как ЗащищенноеСоединениеOpenSSL), нет поддержки расширения SNI (Server Name Indication) и современных криптографических протоколов TLS 1.2 / TLS 1.3. Поскольку большинство современных серверов запрещают соединения по протоколам SSLv3 и TLS 1.0, прямое обращение через WSПрокси или HTTPСоединение завершается ошибкой рукопожатия.
Рассмотрим основные способы решения данной задачи.
Вместо штатных объектов платформы 1С мы можем воспользоваться системными сетевыми компонентами операционной системы Windows — WinHttp.WinHttpRequest.5.1 или MSXML2.ServerXMLHTTP.6.0. Эти библиотеки используют встроенный в операционную систему криптопровайдер Schannel, автоматически работают с системным хранилищем доверенных корневых сертификатов Windows и поддерживают протоколы TLS 1.2 и TLS 1.3.
Разберем пример отправки SOAP-запроса через WinHttp.WinHttpRequest.5.1:
// Создаем тело SOAP-пакета
ТекстЗапросаXML =
"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:web=""http://example.com/webservice"">" +
" <soapenv:Header/>" +
" <soapenv:Body>" +
" <web:GetData>" +
" <web:Param>12345</web:Param>" +
" </web:GetData>" +
" </soapenv:Body>" +
"</soapenv:Envelope>";
// Инициализируем COM-объект WinHTTP
Попытка
HTTPЗапрос = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
HTTPЗапрос.Open("POST", "https://api.example.com/service.asmx", Ложь);
HTTPЗапрос.SetRequestHeader("Content-Type", "text/xml; charset=utf-8");
HTTPЗапрос.SetRequestHeader("SOAPAction", "http://example.com/webservice/GetData");
HTTPЗапрос.Send(ТекстЗапросаXML);
Если HTTPЗапрос.Status = 200 Тогда
ОтветXML = HTTPЗапрос.ResponseText;
// Разбираем полученный XML штатными средствами 1С
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ОтветXML);
// Дальнейшая обработка данных
Иначе
Сообщить("Ошибка вызова веб-сервиса: " + HTTPЗапрос.Status + " " + HTTPЗапрос.StatusText);
КонецЕсли;
Исключение
Сообщить("Не удалось выполнить запрос: " + ОписаниеОшибки());
КонецПопытки;
Если требуется сохранить работу через штатные механизмы 1С (например, использовать типизированный WSПрокси), можно применить локальный прокси-сервер (такой как stunnel или Nginx).
Схема взаимодействия выглядит следующим образом:
http://localhost:8080/service).Если целевой сервер поддерживает устаревшие протоколы TLS, но ошибка возникает из-за отсутствия корневого сертификата в доверенном списке платформы, выполним следующие действия:
cacert.pem в каталоге установки платформы (по умолчанию bin\cacert.pem).cacert.pem.WSОпределения передадим путь к локальному файлу схемы:
ПутьКФайлуWSDL = "C:\WSDL\service.wsdl";
Определения = Новый WSОпределения(ПутьКФайлуWSDL);
Прокси = Новый WSПрокси(Определения, "http://example.com/webservice", "ServiceName", "ServiceSoapPort");
Если в инфраструктуре предприятия развернуты современные версии 1С:Предприятие (8.3), эффективным архитектурным решением является вынос взаимодействия с внешними защищенными API в отдельную сервисную базу. База на 8.1 обращается к промежуточной базе по протоколу COM или через внутренний HTTP-сервис, а промежуточная база выполняет защищенное TLS-соединение с помощью объекта ЗащищенноеСоединениеOpenSSL.