CertPathValidatorException: Trust anchor for certification path not found c DigiCert сертификатом
Дано:
Android девайсы разных вендоров, все в Индии. Версии ОС - все (от 5 до 14 Android). Всего больше сотни разных девайсов, вот первый десяток моделей:
M2010J19SI CPH2579 MT2111 SM-M315F 220733SI CPH2139 CPH1933 EB2101 RMX3780Сервер с платным сертификатом для TLS -
DigiCert Global Root G2(https://www.digicert.com/kb/digicert-root-certificates.htm)Приложение, отправляющее сетевые запросы с девайсов из п1 на сервер из п2, используя либу
OkHttp
Проблема:
Указанные девайсы, судя по информации, которую программно собираем - не могут до сервера достучаться из-за SSL ошибки.
В системе сбора статистики наблюдаем ошибки такого вида:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Предположение:
На девайсах отсутствует нужный сертификат в списке доверенных сертификатов системы.
Подтверждение предположения:
- Берём любой девайс/эмулятор
- Отключаем в его настройках сертификат из п2 Дано (на эмуляторе отключать тут:
Settings->Security->Encryption&Credentials->Trusted credentials) - см скриншот.
Пробуем отправить сетевой запрос - получаем ошибку аналогичную наблюдаемой в системе сбора ошибок.
Вручную вшиваем отключенный сертификат в приложение вот так:
добавляем файл сертификата (
digi_cert_global_cag2) в res/rawсоздаём в res/xml файл network_security_config с содержимым:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted=“false">
<trust-anchors>
<certificates src="@raw/digi_cert_global_cag2" />
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
- прописываем конфиг в манифесте:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
…
<application
android:networkSecurityConfig="@xml/network_security_config"
…
- Сетевые запросы теперь успешно отправляются.
Проблема:
- Ручное вшивание в приложение сертификата не решило проблему - девайсы указанные продолжают генерировать
SSLошибку, о чём сообщает нам наша система сборка ошибок. - Девайса на котором проблема воспроизводится без ручного отключения сертификата в наличии нет
Неподходящие решения:
Использовать обычный LetsEnctypt сертификат - не вариант, ибо требуется платный сертификат по требованию третьих сторон.
Вопросы:
- Кто-то с таким сталкивался?
- Что делать?
Игнорировать эту ошибку (случается у крайне незначительного кол-ва юзеров) тоже не вариант - DevOps-ы резко против
