При разработке мобильных приложений на платформе 1С:Предприятие часто возникает необходимость организации безопасного обмена данными с веб-сервисами через протокол HTTPS. Если на десктопной версии 1С самоподписанные сертификаты (self-signed) работают без особых усилий, то мобильная платформа Android предъявляет гораздо более жесткие требования к безопасности. Разберем подробно, почему возникает ошибка Hostname not verified, и как правильно настроить окружение и код 1С для стабильной работы.
Проанализируем типичную ситуацию. Программист генерирует сертификат через OpenSSL, устанавливает его на сервер Apache и прописывает путь к файлу сертификата в коде 1С. На настольном компьютере вызов веб-сервиса через ЗащищенноеСоединениеOpenSSL проходит успешно, но при запуске на Android-устройстве система выдает ошибку верификации. Выясним основные причины такого поведения:
Common Name (CN) при проверке соответствия сертификата адресу сервера. Если вы обращаетесь к серверу по IP-адресу (например, 192.168.1.2), этот адрес должен быть явно указан в расширении SAN.sdcard/Download/ может быть ограничен политиками безопасности Android (Scoped Storage), что делает невозможным чтение файла сертификата кодом 1С.Рассмотрим процесс создания сертификата через OpenSSL. Обычного указания IP в поле Common Name недостаточно. Нам необходимо создать конфигурационный файл для OpenSSL, который «зашьет» альтернативное имя хоста в тело сертификата. Создадим файл server.cnf со следующим содержимым:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = v3_ca
[dn]
C = RU
ST = Moscow
L = Moscow
O = MyCompany
OU = IT
CN = 192.168.1.2
[v3_ca]
subjectAltName = @alt_names
[alt_names]
IP.1 = 192.168.1.2
DNS.1 = mycloud.local
Проанализируем этот файл: в секции [alt_names] мы указываем как IP-адрес, так и DNS-имя. Теперь выполним команду для выпуска сертификата:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt -config server.cnf
Этот метод гарантирует, что Android сможет сопоставить адрес сервера (192.168.1.2) с данными внутри сертификата. Если в коде 1С используется IP-адрес, Android проверит поле IP.1, если доменное имя — поле DNS.1.
Посмотрим на пример реализации защищенного соединения в мобильном приложении. Важно понимать, что на Android передача пути к файлу сертификата в конструктор ЗащищенноеСоединениеOpenSSL должна сопровождаться правильной обработкой местоположения этого файла.
Рассмотрим правильный подход к инициализации соединения:
// Определим путь к сертификату во внутреннем хранилище приложения
ПутьКСертификату = "sdcard/Download/server101.mycloud.public.pem";
// Для Android лучше использовать внутренние папки приложения
// ПутьКСертификату = ДокументыПриложения() + "/server.crt";
ПарольСертификата = "ВашПароль"; // Если сертификат защищен паролем
СертификатКлиента = Новый СертификатКлиентаФайл(ПутьКСертификату, ПарольСертификата);
// Инициализируем защищенное соединение
// Первый параметр - сертификат клиента, второй - сертификаты удостоверяющих центров (СА)
Защита = Новый ЗащищенноеСоединениеOpenSSL(СертификатКлиента);
// Пытаемся создать определение веб-сервиса
Попытка
ВСОпределения = Новый WSОпределения(АдресWSDL, Пользователь, Пароль, Защита);
// Дальнейшая работа с прокси
Исключение
Сообщить("Ошибка соединения: " + ОписаниеОшибки());
КонецПопытки;
Обратите внимание: если вы используете самоподписанный сертификат, который сам является корневым, его часто нужно передавать вторым параметром в ЗащищенноеСоединениеOpenSSL как часть массива доверенных сертификатов, либо устанавливать в системное хранилище Android.
Выясним, как правильно «подружить» Android с нашим самодельным сертификатом. Простого копирования файла в память телефона недостаточно. Пройдем по шагам:
server.crt на устройство.Важный момент: Начиная с Android 7.0 и выше, приложения 1С могут игнорировать этот сертификат, так как он находится в пользовательском хранилище. Если ошибка CertPathValidatorException или Hostname not verified сохраняется после добавления SAN, это означает, что мобильная платформа 1С ограничена системными настройками безопасности. В таких случаях рекомендуется использовать полноценные бесплатные сертификаты (например, Let's Encrypt), если сервер имеет выход в интернет, так как их корневые центры уже доверены Android "из коробки".
Проанализируем ситуацию с ошибкой доступа к файлу сертификата. В новых версиях Android путь sdcard/Download/ может быть недоступен приложению напрямую без специальных разрешений. Выясним, как это обойти:
Вместо жесткого прописывания путей, рекомендуется предварительно копировать файл сертификата в доступную область приложения. Используйте функцию СредстваГеопозиционирования.ПолучитьКаталогДокументов() (или аналогичные методы для получения пути к папке документов приложения) для определения легитимного пути, где 1С гарантированно сможет прочитать файл без конфликтов с операционной системой.
ИмяФайлаСерта = "myserver.crt";
ПутьКФайлу = ОбъединитьПути(КаталогДокументов(), ИмяФайлаСерта);
// Проверяем наличие файла перед созданием соединения
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если Не ФайлНаДиске.Существует() Тогда
Сообщить("Файл сертификата не найден по пути: " + ПутьКФайлу);
Иначе
Защита = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаФайл(ПутьКФайлу));
КонецЕсли;
Для успешного использования самоподписанного SSL в 1С на Android придерживайтесь следующих правил:
Hostname.myserver.local, а не по IP. Это упрощает прохождение проверок безопасности.Соблюдение этих технических нюансов позволит вам избежать нервных срывов при отладке мобильных решений и обеспечит надежное защищенное соединение между вашим приложением на Android и учетной системой 1С.