Библиотека kotlin, которая может выполнять httpS-соединение без проверки сертификата (например, curl --insecure)

Мне нужно сканировать внутренний сайт компании с истекшим сроком действия / самоподписанный сертификат. Никто никогда не собирается настраивать действительный сертификат для этого хоста, поэтому я должен использовать незащищенное соединение.

curl имеет --insecure флаг для этой цели,

Библиотека Scala Finagle имеет .tlsWithoutValidation() Режим.

ВОПРОС: Есть ли библиотека Kotlin, у которой есть подобная опция?

UPD: пока я использую Fuel с явным обходным путем, найденным здесь, но все еще ищу лучшие пути..

fun useInsecureSSL() {

    // Create a trust manager that does not validate certificate chains
    val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
        override fun getAcceptedIssuers(): Array<X509Certificate>? = null
        override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) = Unit
        override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) = Unit
    })

    val sc = SSLContext.getInstance("SSL")
    sc.init(null, trustAllCerts, java.security.SecureRandom())
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory)

    // Create all-trusting host name verifier
    val allHostsValid = HostnameVerifier { _, _ -> true }

    // Install the all-trusting host verifier
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid)
}

Описанный выше обходной путь работает, однако он слишком многословен и, по-видимому, устанавливает небезопасный режим для каждого соединения, установленного моим приложением, а не только для конкретного.

0 ответов

Fuel позволяет создавать свой собственный экземпляр клиента Fuel через FuelManager учебный класс. Менеджер позволяет вам установить свой собственный HostnameVerifier а также SSLSocketFactory а затем создает клиента с настроенными. См. https://github.com/kittinunf/Fuel/blob/1.16.0/fuel/src/main/kotlin/com/github/kittinunf/fuel/core/FuelManager.kt#L31-L43

val manager : FuelManager = FuelManager().apply {
  val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
    override fun getAcceptedIssuers(): Array<X509Certificate>? = null
    override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) = Unit
    override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) = Unit
  })

  socketFactory = SSLContext.getInstance("SSL").apply {
    init(null, trustAllCerts, java.security.SecureRandom())
  }.socketFactory

  hostnameVerifier = HostnameVerifier { _, _ -> true }
}

Затем проверить, что только соединения, которые проходят через этот кастом FuelManager нам не доверяют, а соединениям, которым не доверяют, мы делаем это:

val (_, untrustedResp, untrustedResult) = manager.request(Method.GET, "https://internal/company/site").response()
assert(untrustedResp.statusCode == 200)
val (bytes, _) = untrustedResult
assert(bytes != null)


val (_, trustedResp, trustedResult) = "https://internal/company/site".httpGet().response()
assert(trustedResp.statusCode != 200)
val (bytes, error) = trustedResult
assert(bytes == null)
println(error) // javax.net.ssl.SSLHandshakeException: PKIX path building failed: ...

Обычай FuelManager удалось успешно выполнить запрос, потому что он доверяет всем сертификатам, но для соединения, которое не использует пользовательский менеджер, мы видим, что он возвращается с javax.net.ssl.SSLHandshakeException,

Спасибо, @ludenus, @ Джейсон Йео.

Если вы используете Fuel и хотите преодолеть старую проблему SSL-сертификата, то в вашем Api-классе, где вы храните все запросы, напишите, что они предложили. Это решение не проверяет URL-адреса, оно разрешает запросы на любые URL-адреса.

import com.github.kittinunf.fuel.core.FuelManager
import com.github.kittinunf.fuel.core.Method
import com.github.kittinunf.fuel.core.Request
import com.github.kittinunf.fuel.httpPost
import java.security.cert.X509Certificate
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

class ApiImpl : Api {

    init {
        FuelManager.instance.basePath = Api.SERVER_URL // Your usual URL.

        FuelManager.instance.apply {
            val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
                override fun getAcceptedIssuers(): Array<X509Certificate>? = null
                override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) =
                    Unit
                override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) =
                    Unit
            })

            socketFactory = SSLContext.getInstance("SSL").apply {
                init(null, trustAllCerts, java.security.SecureRandom())
            }.socketFactory

            hostnameVerifier = HostnameVerifier { _, _ -> true }
        }
    }

    /**
     * Your requests stay intact.
     */
    override fun getSomething(id: Int): Request =
        "getinfo/".httpPost(listOf("id" to id))
}
Другие вопросы по тегам