При интеграции 1С:Предприятия с внешними веб-сервисами по протоколу HTTPS часто требуется использование двусторонней аутентификации (mTLS), где клиент (наша 1С) должен предъявить свой сертификат серверу. Платформа предоставляет удобный механизм для работы с системным хранилищем сертификатов Windows, однако разработчики нередко сталкиваются с ситуацией, когда ожидаемое диалоговое окно выбора сертификата не появляется, и соединение разрывается или проходит без сертификата. В этой статье мы подробно разберем причины такого поведения, проанализируем код и выясним, как правильно диагностировать проблемы с SSL-рукопожатием.
Рассмотрим типичный пример кода, который должен вызывать диалог выбора сертификата. Именно такой подход обычно используется разработчиками:
// Указываем, что хотим выбирать сертификат вручную через системный диалог
СпособВыбораСертификата = Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Выбирать);
// Создаем защищенное соединение, используя хранилище Windows
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(СпособВыбораСертификата, Новый СертификатыУдостоверяющихЦентровWindows());
// Инициализируем HTTP-соединение
Соединение = Новый HTTPСоединение(server, 443,,,,, ЗащищенноеСоединение);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=UTF-8");
Запрос = Новый HTTPЗапрос("/", Заголовки);
// Выполняем запрос
Ответ = Соединение.Получить(Запрос);
В данном коде используется параметр СпособВыбораСертификатаWindows.Выбирать. Согласно документации, при наличии более одного подходящего клиентского сертификата пользователю должен предоставляться выбор через системный диалог. Однако на практике окно часто не появляется. Разберемся, почему это происходит.
Первый вопрос, который возникает у разработчиков: "После какой строчки кода должно появиться окно?".
Важно понимать, что создание объекта HTTPСоединение не инициирует сетевую активность. Конструктор просто сохраняет параметры подключения. Реальное TCP-соединение и последующее SSL/TLS-рукопожатие (Handshake) происходят "лениво" — в момент первого вызова метода, отправляющего данные (например, Получить(), ОтправитьДляОбработки() и т.д.).
Следовательно, системный диалог может появиться только при исполнении строки:
Ответ = Соединение.Получить(Запрос);
Если до этой строки выполнение доходит без ошибок, но окно не появляется, проблему нужно искать в процессе согласования соединения.
Это наиболее распространенная причина отсутствия диалога. Механизм SSL/TLS устроен так, что клиент отправляет свой сертификат **только если сервер этого явно потребовал**. Процесс рукопожатия выглядит упрощенно так: 1. **Client Hello**: 1С отправляет приветствие. 2. **Server Hello**: Сервер отвечает, присылает свой сертификат. 3. **Certificate Request**: (Опционально!) Сервер запрашивает сертификат у клиента. 4. **Client Certificate**: 1С показывает окно выбора (если нужно) и отправляет выбранный сертификат. Если на веб-сервере, к которому вы подключаетесь (IIS, Apache, Nginx), настройка клиентских сертификатов стоит в режиме **"Ignore"** (Игнорировать) или **"None"**, сервер пропускает шаг №3. Windows (и библиотека OpenSSL внутри 1С) видят, что запрос не пришел, и, соответственно, не инициируют диалог выбора, так как отправлять нечего. Для появления окна сервер должен быть настроен в режим **"Accept"** (Принимать) или **"Require"** (Требовать).
Даже если сервер запрашивает сертификат, он обычно передает список "доверенных издателей" (Distinguished Names of Acceptable CAs). Это список удостоверяющих центров, которым доверяет сервер. Рассмотрим механизм фильтрации на клиенте: 1. Windows получает от сервера список доверенных центров. 2. Операционная система сканирует личное хранилище пользователя. 3. Отбираются только те сертификаты, которые были выданы центрами из полученного списка (или цепочка доверия которых ведет к этим центрам). 4. Если после фильтрации не осталось ни одного сертификата, окно выбора не откроется (либо соединение разорвется, либо продолжится анонимно, в зависимости от строгости настроек). Если у вас установлено два сертификата, но ни один из них не подходит под требования сервера (выдан "не тем" удостоверяющим центром), список выбора будет пуст, и диалог не появится.
Чтобы сертификат попал в выборку объекта СертификатКлиентаWindows, он должен соответствовать техническим требованиям аутентификации:
В коде используется гибридная конструкция:
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(СпособВыбораСертификата, ...);
Здесь транспортный уровень обеспечивает встроенная в платформу библиотека OpenSSL, но ключи она берет из хранилища Windows (CryptoAPI). Иногда возникают конфликты на стыке этих технологий.
Важно помнить, что диалоговое окно — это элемент пользовательского интерфейса.
* Если код выполняется **НаСервере**, никакого окна не появится, так как серверный процесс не интерактивен. В этом случае нужно использовать СпособВыбораСертификатаWindows.Авто, и сертификат должен быть единственным подходящим.
* Если код выполняется в веб-клиенте (браузере), то управление сертификатами полностью берет на себя браузер, и код 1С на это влияет слабо. Окно выбора покажет сам браузер.
Если окно не открывается, мы рекомендуем выполнить следующие шаги для поиска причины:
Шаг 1. Проверка через браузер
На том же компьютере, где запущена 1С, откройте Internet Explorer или классический Edge (они используют тот же системный стек, что и 1С при работе с сертификатами Windows). Введите адрес сервера (https://server...).
* Если браузер **показал** окно выбора сертификата — проблема в 1С или параметрах вызова.
* Если браузер **молча** открыл страницу (без замка или с обычным замком) — значит, сервер не требует сертификат.
* Если браузер выдал ошибку соединения (403 Forbidden и т.д.) без запроса сертификата — значит, сертификаты отфильтрованы и не подходят серверу.
Шаг 2. Проверка доступности портов
В обсуждении предлагали проверить порт 80. Это имеет смысл только для проверки физической доступности сервера.
// Тест связи без SSL
Соединение = Новый HTTPСоединение(server, 80);
Если через порт 80 соединение не проходит вовсе, значит проблема сетевая (Firewall, DNS, отсутствие маршрута), и сертификаты здесь ни при чем.
Шаг 3. Анализ свойств сертификата
Откройте сертификат в Windows (certmgr.msc -> Личные). Убедитесь, что:
* Есть закрытый ключ.
* В назначении есть "Проверка подлинности клиента".
* Цепочка сертификации (Путь сертификации) построена корректно и все корневые сертификаты доверены.
Отсутствие окна выбора сертификата при использовании СпособВыбораСертификатаWindows.Выбирать практически всегда указывает на то, что с точки зрения операционной системы выбирать не из чего, либо сервер не инициировал этот выбор. Проверяйте настройки веб-сервера на требование `Client Certificate` и соответствие ваших сертификатов списку доверенных центров, которые присылает сервер.