Ошибка связи CLEARTEXT с xxx, не разрешенной политикой сетевой безопасности, возникает, когда я подключаю сервер API с помощью tls 1.2 для модернизации. Я знаю, что эта ошибка возникает при подключении к http, есть ли другая причина? Я что-то пропустил? Мой сервер API совместим только с tls 1.2 Мой проект нацелен на SDK 33, модифицированная версия 2.9.0, okhttp 4.9.2
я не хочу так использовать
Сначала был изменен только адрес, но это не сработало, поэтому сделайте сертификат ca с fullchain.pem и добавьте клиента, используя ok http, возникает вышеуказанная ошибка.
object RetrofitObj {
private const val BASE_URL = base_api_url
fun create(context: Context): Retrofit {
val tmf: TrustManagerFactory? = getTrustManagerFactory(context)
var sslsocket = tmf?.let { getSSLSocketFactory(it) }
val hostnameVerifier = HostnameVerifier { _, session ->
HttpsURLConnection.getDefaultHostnameVerifier().run {
verify(VERIFY_DOMAIN, session)
}
}
val client = sslsocket?.let {
OkHttpClient.Builder()
.sslSocketFactory(it, tmf?.trustManagers?.get(0) as X509TrustManager)
.hostnameVerifier(hostnameVerifier)
.build()
}
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
private fun getTrustManagerFactory(context: Context): TrustManagerFactory? {
val cf: CertificateFactory = CertificateFactory.getInstance("X.509")
val caInput: InputStream = context.resources.openRawResource(R.raw.fullchain2)
val ca: X509Certificate = caInput.use {
cf.generateCertificate(it) as X509Certificate
}
val keyStoreType = KeyStore.getDefaultType()
val keyStore = KeyStore.getInstance(keyStoreType).apply {
load(null, null)
setCertificateEntry("ca", ca)
}
val tmfAlgorithm: String = TrustManagerFactory.getDefaultAlgorithm()
val tmf: TrustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm).apply {
init(keyStore)
}
return tmf
}
private fun getSSLSocketFactory(
tmf: TrustManagerFactory
): SSLSocketFactory? {
val sslContext: SSLContext = SSLContext.getInstance("TLS")
sslContext.init(null, tmf.trustManagers, null)
return sslContext.socketFactory
}
@JoachimSauer Мой сервер API использует LetsEncrypt
Тогда почему ваш HostnameVerifier игнорирует переданное имя хоста? Он должен передать это верификатору по умолчанию и, при желании (что, вероятно, не нужно) также проверить, что имя хоста соответствует ожидаемому. Я не уверен, что это реальная проблема, но это может уже сбить обнаружение.
Давайте посмотрим эту статью: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
По сути, CSP (политика безопасности контента) — это дополнительный уровень безопасности, направленный на защиту от внедрения данных и XSS (межсайтовых сценариев).
Чтобы включить CSP, ваш веб-сервер должен вернуть заголовок Content-Security-Policy (см. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
Его синтаксис
Content-Security-Policy: <policy-directive>; <policy-directive>
где директива политики (элементы, разделенные точкой с запятой) всегда имеет форму
<directive> <value>
Кроме того, вместо заголовка ответа вы также можете использовать тег meta для того же эффекта. Пример:
<meta
http-equiv = "Content-Security-Policy"
content = "default-src 'self'; img-src https://*; child-src 'none';" />
Итак, когда вы получаете сообщение об ошибке с жалобой на нарушение CSP, вам необходимо проверить следующие элементы:
Теперь, когда у вас есть все необходимое для решения этой проблемы, вам нужно будет проверить, что такое политика, какая попытка действия была предотвращена ею, и внести изменения в ваш CSP, которые удостоверятся, что CSP разрешит это действие в будущее, если вы хотите позволить это.
В противном случае, если это то, чего вы изначально не хотели, выясните, почему происходит упомянутое поведение, и выполните необходимые действия.
Насколько мне известно, эта ошибка относится ко всем видам нестандартных (читай: «в некотором роде небезопасных») настроек TLS. Это может быть ваш собственный HostnameVerifier или какой-то другой аспект, который вызывает обнаружение. Есть ли причина, по которой вы не можете использовать простой старый общедоступный доверенный сертификат (например, вы можете получить его бесплатно с помощью LetsEncrypt)?