kotlin library that can do httpS connection without certificate verification (like curl --insecure)

给你一囗甜甜゛ 提交于 2019-12-23 09:15:13

问题


I need to crawl internal company site that has expired/self-signed certificate. Noone is ever going to configure valid certificate for that host, so I have to use insecure connection.

curl has --insecure flag for that purpose,

Scala finagle library has .tlsWithoutValidation() mode.

QUESTION: Is there a Kotlin library that has similar option?

UPD: so far I am using Fuel with the javish workaround found here but still searching for better ways..

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)
}

The above workaround works however it is too verbose and seems to set insecure mode for every connection made by my app, not only for the particular one.


回答1:


Fuel allows you to create your own instance of the Fuel client through the FuelManager class. The manager lets you can set your own HostnameVerifier and SSLSocketFactory and then creates a client with those configured. See 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 }
}

Then to check that only connections that goes through this custom FuelManager is untrusted and connections that don't are trusted, we do this:

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: ...

The custom FuelManager was able to make the request successfully because it trusts all certs but for the connection that didn't use the custom manager, we can see that it returns with javax.net.ssl.SSLHandshakeException.



来源:https://stackoverflow.com/questions/47460211/kotlin-library-that-can-do-https-connection-without-certificate-verification-li

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!