问题
I have the following kotlin code:
val urlPath = "https://10.0.2.2:8080"
var data: String
try {
data = URL(urlPath).readText()
} catch (e: Exception) {
Log.e("doInBackground", "Exception caught: ${e.localizedMessage}")
error = when (e) {
is MalformedURLException -> "Invalid URL"
is IOException -> "Network Error"
else -> {
"Network error: ${e.localizedMessage}"
}
}
}
If I use the above code to connect to a http server, the above code works. However when I try to connect to a https server with a self-signed certificate, it fails. Is there a way to allow https connections on localhost (only), even when the certificates are self-signed ?
回答1:
Here's an example that reads from https://google.com using JSSE, it trusts literally every certificate and shouldn't be used productively.
fun main(args: Array<String>) {
val urlPath = "https://google.com"
try {
(URL(urlPath).openConnection() as HttpsURLConnection).apply {
sslSocketFactory = createSocketFactory(listOf("TLSv1.2"))
hostnameVerifier = HostnameVerifier { _, _ -> true }
readTimeout = 5_000
}.inputStream.use {
it.copyTo(System.out)
}
} catch (e: Exception) {
TODO()
}
}
private fun createSocketFactory(protocols: List<String>) =
SSLContext.getInstance(protocols[0]).apply {
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) = Unit
override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) = Unit
})
init(null, trustAllCerts, SecureRandom())
}.socketFactory
I've got a little library for these kinds of things here, which is neither up-to-date nor published. Nevertheless, it provides a simple DSL for setting up TLS/SSL sockets and provides means for https connections.
来源:https://stackoverflow.com/questions/49032463/kotlin-connect-to-self-signed-https-server