При разработке мобильных приложений на платформе 1С:Предприятие одной из приоритетных задач является обеспечение безопасности передаваемых данных. Для защиты каналов связи от перехвата и подмены данных (атак типа «человек посередине» или Man-in-the-Middle) традиционно используется протокол HTTPS. Однако на этапе развертывания и тестирования разработчики регулярно сталкиваются с ошибкой: «Ошибка работы с Интернет: Удаленный узел не прошел проверку». Данная ошибка возникает при вызове методов HTTP-соединения, таких как Получить() или ОтправитьДляОбработки().
В этой статье мы подробно разберем, почему возникает эта ошибка, как правильно генерировать SSL-сертификаты, настроить веб-сервер Apache и обойти специфические ограничения современных мобильных операционных систем Android и iOS.
Рассмотрим стандартный сценарий подключения из кода 1С, который часто используют разработчики для тестирования соединения с использованием собственного центра сертификации (CA):
ПутьКФайлу = "E:\ssl\Mobile\CA_Test.crt";
СертификатЦА = Новый СертификатыУдостоверяющихЦентровФайл(ПутьКФайлу);
SSL = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, СертификатЦА);
Попытка
тСоединение = Новый HTTPСоединение(Адрес, Порт, Логин, Пароль, , , SSL);
тHTTPЗапрос = Новый HTTPЗапрос(ТекстЗапроса);
тHTTPОтвет = тСоединение.Получить(тHTTPЗапрос);
тОтвет = тHTTPОтвет.ПолучитьТелоКакСтроку();
Исключение
Сообщить("Не удалось установить соединение. " + ОписаниеОшибки());
КонецПопытки;
При запуске этого кода платформа выдает исключение. Если обратиться к логам веб-сервера Apache, мы можем обнаружить, что запросы от клиента даже не доходят до сервера. Это происходит потому, что подсистема безопасности OpenSSL на стороне клиента (в данном случае — платформы 1С) разрывает TLS-рукопожатие (Handshake) еще до отправки HTTP-пакета, так как серверный сертификат не проходит проверку на соответствие стандартам безопасности.
Давайте разберем основные причины этой проблемы и пошагово решим каждую из них.
Самая распространенная ошибка при создании самоподписанных сертификатов — несоответствие адреса, к которому обращается программа, и имени, указанного в самом сертификате.
В процессе рукопожатия клиент сравнивает строку подключения из параметра Адрес объекта HTTPСоединение (например, 10.10.10.1 или myserver.local) с данными внутри присланного сервером сертификата:
10.10.10.1, а в поле CN написано MyTestServer, проверка провалится с ошибкой несоответствия адреса.CN устаревшим (deprecated) и требуют обязательного наличия расширения SAN (Subject Alternative Name).Если веб-сервер доступен по IP-адресу в локальной сети, этот IP-адрес должен быть явно задекларирован в блоке SAN как IP-адрес, а не DNS-имя. Давайте посмотрим на правильный пример конфигурационного файла OpenSSL (openssl.cnf) для генерации такого сертификата:
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name (full name)
localityName = Locality Name (eg, city)
organizationName = Organization Name (eg, company)
commonName = Common Name (e.g. server FQDN or YOUR name)
[ v3_req ]
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
IP.1 = 10.10.10.1
DNS.1 = myserver.local
При генерации сертификата сервера обязательно используйте это расширение, чтобы современные операционные системы не отклоняли сертификат из-за отсутствия альтернативных имен субъекта.
Даже если проверка в толстом клиенте 1С на Windows проходит успешно после исправления сертификатов, при переносе решения на мобильное устройство под управлением Android или iOS вы гарантированно столкнетесь с новыми трудностями.
Особенности Android (начиная с версии 7.0 Nougat):
В современных версиях Android операционная система по умолчанию больше не доверяет сертификатам, добавленным пользователем в системное хранилище (User CA). Ваше мобильное приложение 1С будет игнорировать установленный на телефоне файл CA_Test.crt. Чтобы решить эту проблему при сборке мобильного приложения, необходимо настроить конфигурацию сетевой безопасности (Network Security Config).
Для этого в проект сборки мобильного приложения добавляется файл конфигурации безопасности XML (например, network_security_config.xml):
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
Этот файл принудительно заставляет операционную систему доверять сертификатам из пользовательского хранилища. Укажите этот файл при сборке APK в сборщике мобильных приложений 1С.
Особенности iOS:
На мобильных устройствах Apple недостаточно просто установить корневой профиль сертификата. Вам необходимо вручную зайти в меню устройства: Настройки -> Основные -> Об этом устройстве -> Доверие сертификатам и активировать переключатель полного доверия для вашего установленного корневого сертификата CA.
Если перед вами стоит задача обеспечить максимальную безопасность (например, гарантировать, что к вашему Apache-серверу могут подключаться только авторизованные мобильные клиенты с установленными ключами), необходимо использовать двустороннее TLS-соединение. В этом случае не только клиент проверяет сервер, но и сервер требует от клиента сертификат.
Для этого нам потребуется сгенерировать клиентский сертификат в формате PKCS#12 (файл с расширением .p12 или .pfx), содержащий закрытый ключ клиента. В коде мобильного приложения инициализация такого соединения будет выглядеть следующим образом:
// Путь к файлу клиентского сертификата в памяти мобильного устройства
ПутьККлиентскомуСертификату = КаталогДокументов() + "client.p12";
ПарольКСертификату = "ВашПарольККлючу";
СертификатКлиента = Новый СертификатКлиентаФайл(ПутьККлиентскомуСертификату, ПарольКСертификату);
СертификатЦА = Новый СертификатыУдостоверяющихЦентровФайл(ПутьКФайлуЦА);
SSL = Новый ЗащищенноеСоединениеOpenSSL(СертификатКлиента, СертификатЦА);
Попытка
тСоединение = Новый HTTPСоединение(Адрес, Порт, , , , , SSL);
// Отправка запроса...
Исключение
Сообщить("Ошибка авторизации по mTLS: " + ОписаниеОшибки());
КонецПопытки;
На стороне веб-сервера Apache для поддержки этого режима необходимо включить проверку клиентских сертификатов в конфигурационном файле виртуального хоста (обычно это ssl.conf или httpd-ssl.conf):
SSLEngine on
SSLCertificateFile "/etc/ssl/certs/server.crt"
SSLCertificateKeyFile "/etc/ssl/private/server.key"
SSLCACertificateFile "/etc/ssl/certs/CA_Test.crt"
# Требовать клиентский сертификат для авторизации
SSLVerifyClient require
SSLVerifyDepth 10
В версиях платформы 1С:Предприятие 8.3.12 и выше был изменен внутренний механизм валидации сертификатов. Теперь платформа по умолчанию пытается проверить статус отзыва сертификата через системные службы операционной системы (используя протоколы CRL и OCSP).
Если ваша центральная база 1С или сервер лицензирования находятся в закрытом локальном контуре без прямого доступа к глобальной сети Интернет, попытка проверить статус отзыва самоподписанного сертификата завершится тайм-аутом, и платформа вернет всё ту же ошибку: «Удаленный узел не прошел проверку».
Чтобы отключить эту строгую проверку в изолированных сетях, необходимо отредактировать конфигурационный файл платформы conf.cfg, расположенный в каталоге установки 1С (например, C:\Program Files\1cv8\conf\conf.cfg для Windows или /opt/1C/v8.3/x86_64/conf/conf.cfg для Linux), добавив следующую строку:
IgnoreServerCertificatesChainRevocationSoftFail=true
Этот параметр указывает платформе игнорировать ошибки, связанные с невозможностью связаться с серверами проверки отзывов сертификатов, сохраняя при этом общую валидность цепочки доверия.
Давайте признаем, что администрирование собственного центра сертификации (CA), ручная установка файлов .crt на каждое мобильное устройство сотрудников и пересборка APK-файлов с изменением политик безопасности — это трудоемкий процесс, требующий постоянного контроля сроков действия ключей.
Если у вашей организации есть возможность опубликовать веб-сервер под реальным доменным именем (даже используя динамический DNS) во внешнюю сеть, мы настоятельно рекомендуем отказаться от самоподписанных сертификатов в пользу бесплатных доверенных сертификатов от центра Let's Encrypt. Такие сертификаты признаются операционными системами Android и iOS «из коробки». Вам не придется писать сложный код инициализации ЗащищенноеСоединениеOpenSSL с указанием файлов CA — достаточно будет использовать стандартный конструктор без параметров:
SSL = Новый ЗащищенноеСоединениеOpenSSL();
тСоединение = Новый HTTPСоединение("mydomain.ru", 443, , , , , SSL);
Этот подход гарантирует стабильную работу мобильного приложения на любых пользовательских устройствах без необходимости предварительной настройки их операционных систем.