使用 OkHttp 通过代理的 Https 出现握手错误

Https through proxy with OkHttp got handshake error

我要使用需要 httpsproxyGlide 库下载图片配置。 我为不安全的客户端(在我的开发环境中)实现了所有匿名证书和代理设置,但出现握手错误。这是我的 OkHttpClient 传递给 Glide

val unsafeOkHttpClient: OkHttpClient
        get() {
            try {
                val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
                    @SuppressLint("TrustAllX509TrustManager")
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(
                        chain: Array<java.security.cert.X509Certificate>,
                        authType: String
                    ) {
                    }

                @SuppressLint("TrustAllX509TrustManager")
                @Throws(CertificateException::class)
                override fun checkServerTrusted(
                    chain: Array<java.security.cert.X509Certificate>,
                    authType: String
                ) {
                }

                override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> {
                    return arrayOf()
                }
            })
            val sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, trustAllCerts, java.security.SecureRandom())
            val sslSocketFactory = sslContext.socketFactory
            val builder = OkHttpClient.Builder()
            val proxy = Proxy(
                Proxy.Type.HTTP,
                InetSocketAddress.createUnresolved(PROXY_URL, PROXY_PORT)
            )
            builder.proxy(proxy)

            builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
            builder.hostnameVerifier(HostnameVerifier { _, _ -> true })

            val connectionSpecs = ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
                .tlsVersions(TlsVersion.TLS_1_2)
                .cipherSuites(
                    CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
                    CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
                ).build()

            builder.connectionSpecs(listOf(connectionSpecs))

            return builder.build()
        } catch (e: Exception) {
            throw RuntimeException(e)
        }

    }

我应该提到 ConnectionSpec 是从我的服务器配置中获取的。我总是收到这个错误: 即使我使用了非常简单的客户端,但结果是一样的。

 Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xbe2b3c68: Failure in SSL library, usually a protocol error
    error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (external/boringssl/src/ssl/tls_record.cc:587 0xbe5d2a88:0x00000001)
    error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (external/boringssl/src/ssl/handshake.cc:580 0xd084f543:0x00000000)
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387)
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226)
            ... 23 more

我尝试了太多方法,例如从 glide 中排除 okHttp 并使用 OkHttp 本身,降级 okHttp,升级所有库(Retrofit,Glide)。我在这里找到了一些 posts 但云无法使其工作。

https://github.com/square/okhttp/issues/3787

https://github.com/Microsoft/cpprestsdk/issues/650

已更新

正如我提到的,所有图像都在浏览器中打开(带有代理扩展),而且我还使用 Curl 获得了 200 个图像:

curl --insecure -x http://myProxy:9052 -i  https://myimage.png

但是我发现主服务器和代理服务器的TLS版本不一样。一个使用 TLS1.2,另一个使用 TLS1.1。所以我在想这个配置是否会导致握手失败,因为我的请求不知道与哪个版本握手!这是我的猜测,并且已经询问了网络管理员:"Why we have two different confines for server and proxy!" 我正在等待他们的回复。如果您有任何想法,请随时添加评论或 post 任何答案。

在与客户端进行了许多斗争之后,支持团队设置了一个有效证书,这使我的问题得到了解决。 我的意思是他们没有使用self-sigend证书,但他们使用了无效证书!这就是为什么我收到握手错误,在浏览器中我们可以通过接受危险责任并单击继续按钮来传递此错误。

因此,如果您看到同样的问题:握手错误,但您可以根据我的情况在浏览器中继续,让我们先检查 SSL 证书以节省时间!