Java kotlin连接到自签名https服务器

Java kotlin连接到自签名https服务器,java,android,kotlin,kotlin-android-extensions,kotlin-extension,Java,Android,Kotlin,Kotlin Android Extensions,Kotlin Extension,我有以下kotlin代码: 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 MalformedU

我有以下kotlin代码:

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

如果我使用上述代码连接到http服务器,则上述代码有效。但是,当我尝试使用自签名证书连接到https服务器时,它失败了。有没有一种方法可以允许本地主机上的https连接(仅限),即使证书是自签名的?

下面是一个使用JSSE读取的示例,它完全信任每个证书,不应该有效地使用它

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
fun main(args:Array){
val urlPath=”https://google.com"
试一试{
(URL(urlPath).openConnection()作为HttpsURLConnection.apply{
sslSocketFactory=createSocketFactory(列表(“TLSv1.2”))
hostnameVerifier=hostnameVerifier{{{{,{->true}
readTimeout=5_000
}.inputStream.use{
it.copyTo(System.out)
}
}捕获(e:例外){
待办事项()
}
}
private fun createSocketFactory(协议:列表)=
SSLContext.getInstance(协议[0])。应用{
val trustAllCerts=arrayOf(对象:X509TrustManager{
重写GetAcceptedAssuers():Array=arrayOf()
重写fun checkClientTrusted(证书:数组,authType:String)=单位
override fun checkServerTrusted(证书:数组,authType:String)=单位
})
init(null,trustAllCerts,SecureRandom())
}.袜子厂

我有一个关于这类东西的小图书馆,既不是最新的,也没有出版。然而,它提供了一个用于设置TLS/SSL套接字的简单DSL,并为https连接提供了方法。

服务器是否只允许相互身份验证?否则,您只需要使用自定义TrustStore信任提供的服务器证书。它是一个简单的golang https服务器,通过http.listendServerTLS启动,因此没有额外配置用于相互身份验证。如何使用URL上的kotlin扩展创建信任库?我很难从谷歌上找到这方面的任何代码示例。它不是Kotlin特定的,google for Java JSSET这似乎不起作用。我仍然收到一个异常:
03-01 00:09:27.667 5028-5088/com.example.logindemo E/doInBackground:exception capture:Failed to/10.0.2.2:8080
这个异常对我的等待并没有什么帮助。这是我的一个错误(在错误的端口启动服务器)。代码运行良好。我会接受答案。但是,我要求您只考虑编辑代码以忽略“本地主机”的证书检查(也可能是仅用0.0.2.2来覆盖Android),而不是为所有人打开一个覆盖。谢谢。有人能给我一个消息来源吗?我能从中了解情况吗?虽然它解决了我的问题,但我不明白它是怎么做到的,我真的很想知道到底发生了什么。。