Как быстро исправить ошибки HTTPS на Android 12 и Android 15
Короткий ответ: Android 12 и 15 ужесточили требования к TLS — обязательный HTTPS по умолчанию, строгая проверка цепочки сертификатов, запрет старых алгоритмов и ограничение доверия к пользовательским CA. Чтобы вернуть работоспособность: проверьте цепочку и SNI на сервере, настройте network_security_config для окружений, обновите HTTP‑клиенты и используйте безопасные подходы к pinning и отладке.
Оглавление {{TOC_AUTOMATIC}}
Что поменялось в Android 12 и Android 15
Ключевые изменения, влияющие на работу HTTPS‑соединений:
- Обязательный HTTPS и блокировка plain HTTP, если явно не разрешено (CLEARTEXT not permitted).
- Строже проверяется цепочка сертификатов: отсутствие intermediate, отозванный или просроченный root теперь чаще вызывает ошибку.
- Жёсткие требования к CN/SAN и hostname verification (wildcard должны точно соответствовать).
- Отключение устаревших протоколов/шифров (TLS 1.0/1.1, слабые ciphers) — особенно в Android 15.
- Ограничения на доверие к пользовательским (user‑added) CA — корпоративные прокси и самоподписанные CA могут перестать работать без дополнительных настроек.
Android 12 усилил модель "secure by default"; Android 15 добавил фильтрацию устаревших алгоритмов и ужесточил политику по промежуточным сертификатам и пользовательским CA.
Диагностика сервера и сертификатов — что проверить в первую очередь
Проверьте сервер так, как это видит мобильное приложение, а не браузер.
Шаги проверки:
- Проверка цепочки: убедитесь, что сервер отдает полный набор intermediate‑сертификатов. Многие клиенты не «подтягивают» intermediate за вас.
- Протоколы и шифры: сервер должен поддерживать TLS 1.2+; отключите TLS 1.0/1.1 и слабые cipher suites.
- CN/SAN: SAN должен содержать домен запроса (SNI). При обращении на api.example.com сертификат не может быть на example.com без wildcard.
- Root CA: корневой центр должен быть в системном хранилище доверенных CA; самоподписанные и устаревшие корни — причина CERTIFICATE_UNKNOWN.
- Тесты: curl -v с --tlsv1.2, openssl s_client -showcerts -servername и онлайн/CLI SSL‑чекеры (без ссылок) показывают реальную цепочку.
Не полагайтесь только на браузер: Chrome/WebView может «починить» цепочку, а нативный клиент — нет.
Шаги разработчика: как исправить и не сломать безопасность
- Настройте network_security_config
- Для debug‑сборок можно добавить тестовый CA и разрешить HTTP только на локальных хостах.
- Для release оставьте строгую политику: только HTTPS, строгая проверка hostnames.
Пример минимального network_security_config (debug только для тестового CA):
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.com</domain>
<trust-anchors>
<certificates src="system"/>
</trust-anchors>
</domain-config>
<!-- debug: доверяем локальному CA только в debug-сборке -->
<debug-overrides>
<trust-anchors>
<certificates src="@raw/dev_ca"/>
</trust-anchors>
</debug-overrides>
</network-security-config>
- Обновите HTTP‑клиент и крипто‑библиотеки
- Переходите на актуальные версии OkHttp/Retrofit/Ktor; старые версии могут не поддерживать SNI, TLS 1.2+ или новые CA.
- Уберите самодельные TrustManager’ы, которые отключают валидацию. Если нужно — используйте проверенные библиотеки и стандартные API.
- Корректная отладка сертификатов
- Используйте отдельные конфига для debug; логируйте ошибки SSLHandshakeException с полным стеком.
- Если применяете certificate pinning — подготовьте несколько валидных ключей/сертификатов (backup pins) и документируйте процесс ротации.
- Серверная сторона
- Отдавайте полный chain; периодически проверяйте, не истекает ли intermediate/root.
- Включите поддержку SNI и проверьте виртуальные хосты.
- Настройте OCSP/CRL (если нужно) корректно, но не полагайтесь исключительно на них для базовой валидации.
Для тестовой среды поднимите локальный CA и выдавайте через него сертификаты с правильной цепочкой; добавляйте этот CA только в debug‑конфиг приложения.
Таблица: типичные ошибки и быстрые причины
| Ошибка | Причина | Быстрое исправление |
|---|---|---|
| SSLHandshakeException | несовместимость протоколов/шифров или неполная цепочка | включить TLS1.2+, отдать intermediate |
| SSLPeerUnverifiedException: Hostname mismatch | CN/SAN не совпадает с доменом | выдать сертификат с корректным SAN / использовать правильный URL |
| CERTIFICATE_UNKNOWN | самоподписанный или отозванный root | добавить доверенный CA в debug или использовать публичный CA |
| CLEARTEXT not permitted | запрос идёт по HTTP | включить HTTPS или разрешить HTTP только для конкретных доменов в конфиге |
Частые ошибки
- Отключение проверок в TrustManager ради быстродействия — приводит к MITM‑у.
- Тестовые CA в release‑сборке — клиенты начнут доверять недоверенным центрам.
- Сильный pinning без backup pins — при ротации сертификата приложение перестанет работать.
- Локально всё работает, а на целевых устройствах — нет: не проверяете именно target Android‑версию (12/15).
FAQ
-
Нужно ли всегда переходить на публичный CA?
Для продакшна — да, используйте доверенный публичный CA или правильно развернутую внутреннюю PKI с документированной установкой в приложении. -
Можно ли полностью запретить пользовательские CA?
Да: network_security_config позволяет доверять только системным CA и игнорировать user‑added CA. -
Что делать при ошибках после ротации сертификата?
Убедитесь, что новый сертификат включён в цепочку, имеет корректный SAN и что pinning (если есть) обновлён заранее с использованием backup pins.
Если действовать по шагам — проверить серверную цепочку, привести TLS/шифры в порядок, настроить network_security_config и обновить клиенты — большинство проблем с HTTPS на Android 12 и 15 устраняется быстро и безопасно.