Как настроить работу с самоподписанным SSL-сертификатом в мобильном приложении 1С на Android и исправить ошибку Hostname not verified?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке мобильных приложений на платформе 1С:Предприятие часто возникает необходимость организации безопасного обмена данными с веб-сервисами через протокол HTTPS. Если на десктопной версии 1С самоподписанные сертификаты (self-signed) работают без особых усилий, то мобильная платформа Android предъявляет гораздо более жесткие требования к безопасности. Разберем подробно, почему возникает ошибка Hostname not verified, и как правильно настроить окружение и код 1С для стабильной работы.

Анализ проблемы: почему сертификат работает на Windows, но не на Android?

Проанализируем типичную ситуацию. Программист генерирует сертификат через OpenSSL, устанавливает его на сервер Apache и прописывает путь к файлу сертификата в коде 1С. На настольном компьютере вызов веб-сервиса через ЗащищенноеСоединениеOpenSSL проходит успешно, но при запуске на Android-устройстве система выдает ошибку верификации. Выясним основные причины такого поведения:

  1. Отсутствие Subject Alternative Name (SAN): Современные версии Android игнорируют поле Common Name (CN) при проверке соответствия сертификата адресу сервера. Если вы обращаетесь к серверу по IP-адресу (например, 192.168.1.2), этот адрес должен быть явно указан в расширении SAN.
  2. Политика сетевой безопасности Android (Network Security Config): Начиная с Android 7.0, приложения по умолчанию не доверяют сертификатам, установленным пользователем в хранилище «Пользовательские сертификаты».
  3. Особенности файловой системы: Прямой доступ к путям типа sdcard/Download/ может быть ограничен политиками безопасности Android (Scoped Storage), что делает невозможным чтение файла сертификата кодом 1С.

Шаг 1. Правильная генерация сертификата с использованием SAN

Рассмотрим процесс создания сертификата через 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.

Шаг 2. Настройка программного кода в 1С:Предприятие

Посмотрим на пример реализации защищенного соединения в мобильном приложении. Важно понимать, что на Android передача пути к файлу сертификата в конструктор ЗащищенноеСоединениеOpenSSL должна сопровождаться правильной обработкой местоположения этого файла.

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


// Определим путь к сертификату во внутреннем хранилище приложения
ПутьКСертификату = "sdcard/Download/server101.mycloud.public.pem"; 
// Для Android лучше использовать внутренние папки приложения
// ПутьКСертификату = ДокументыПриложения() + "/server.crt";

ПарольСертификата = "ВашПароль"; // Если сертификат защищен паролем
СертификатКлиента = Новый СертификатКлиентаФайл(ПутьКСертификату, ПарольСертификата);

// Инициализируем защищенное соединение
// Первый параметр - сертификат клиента, второй - сертификаты удостоверяющих центров (СА)
Защита = Новый ЗащищенноеСоединениеOpenSSL(СертификатКлиента);

// Пытаемся создать определение веб-сервиса
Попытка
    ВСОпределения = Новый WSОпределения(АдресWSDL, Пользователь, Пароль, Защита);
    // Дальнейшая работа с прокси
Исключение
    Сообщить("Ошибка соединения: " + ОписаниеОшибки());
КонецПопытки;

Обратите внимание: если вы используете самоподписанный сертификат, который сам является корневым, его часто нужно передавать вторым параметром в ЗащищенноеСоединениеOpenSSL как часть массива доверенных сертификатов, либо устанавливать в системное хранилище Android.

Шаг 3. Установка сертификата на Android-устройство

Выясним, как правильно «подружить» Android с нашим самодельным сертификатом. Простого копирования файла в память телефона недостаточно. Пройдем по шагам:

  1. Перенесите файл server.crt на устройство.
  2. Перейдите в Настройки -> Безопасность -> Установка из памяти устройства -> Сертификат CA (путь может отличаться в зависимости от версии Android).
  3. Установите сертификат.

Важный момент: Начиная с Android 7.0 и выше, приложения 1С могут игнорировать этот сертификат, так как он находится в пользовательском хранилище. Если ошибка CertPathValidatorException или Hostname not verified сохраняется после добавления SAN, это означает, что мобильная платформа 1С ограничена системными настройками безопасности. В таких случаях рекомендуется использовать полноценные бесплатные сертификаты (например, Let's Encrypt), если сервер имеет выход в интернет, так как их корневые центры уже доверены Android "из коробки".

Шаг 4. Решение проблем с путями доступа к файлам

Проанализируем ситуацию с ошибкой доступа к файлу сертификата. В новых версиях Android путь sdcard/Download/ может быть недоступен приложению напрямую без специальных разрешений. Выясним, как это обойти:

Вместо жесткого прописывания путей, рекомендуется предварительно копировать файл сертификата в доступную область приложения. Используйте функцию СредстваГеопозиционирования.ПолучитьКаталогДокументов() (или аналогичные методы для получения пути к папке документов приложения) для определения легитимного пути, где 1С гарантированно сможет прочитать файл без конфликтов с операционной системой.


ИмяФайлаСерта = "myserver.crt";
ПутьКФайлу = ОбъединитьПути(КаталогДокументов(), ИмяФайлаСерта);

// Проверяем наличие файла перед созданием соединения
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если Не ФайлНаДиске.Существует() Тогда
    Сообщить("Файл сертификата не найден по пути: " + ПутьКФайлу);
Иначе
    Защита = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаФайл(ПутьКФайлу));
КонецЕсли;

Резюме и рекомендации

Для успешного использования самоподписанного SSL в 1С на Android придерживайтесь следующих правил:

Соблюдение этих технических нюансов позволит вам избежать нервных срывов при отладке мобильных решений и обеспечит надежное защищенное соединение между вашим приложением на Android и учетной системой 1С.

← На главную