通过OkHttp代理通过Https握手错误 [英] Https through proxy with OkHttp got handshake error

查看:516
本文介绍了通过OkHttp代理通过Https握手错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将使用需要配置 https proxy Glide 库下载图像. 我为不安全的客户端实现了所有匿名证书和代理设置(在我的开发环境中),但是出现握手错误.这是我的 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

我尝试了很多方法,例如从滑行中排除okHttp并使用OkHttp本身,降级okHttp,升级所有库(Retrofit,Glide).

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 .所以我在考虑这种配置可能导致握手失败,导致我的请求不知道与哪个版本进行握手!这是我的猜测,已经问过网络管理员:为什么我们对服务器和代理有两个不同的限制!"我正在等待他们的回应.如果您有任何想法,请随时添加评论或发布任何答案.

解决方案

在客户端处理了很多事情之后,支持团队设置了有效证书,使我的问题得以解决. 我的意思是他们没有使用自我认可证书,但是他们使用了无效的证书!这就是为什么我出现握手错误的原因,在浏览器中,我们可以通过接受危险的责任并单击继续"按钮来传递此错误.

因此,如果您遇到相同的问题:握手错误,但可以根据我的情况在浏览器中进行处理,请先检查SSL证书以节省时间!

I'm going to download image with Glide library that needs https and proxy config. I implemented all anonymous certificates and proxy settings for unsafe client (in my dev environment) but get handshake error. This is my OkHttpClient passed to 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)
        }

    }

I should mention that ConnectionSpec is get from my server configurations. And always i get this error: Even i used very simple client but result is same.

 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

I tried too many ways for example exclude okHttp from glide and use OkHttp itself, downgrade okHttp, upgrade all libs ( Retrofit , Glide ) .I found some posts here but cloud not make it works.

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

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

UPDATED

As i mentioned all images are open in browser ( with proxy extension) and also i got 200 with Curl like this:

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

But i find out that TLS version of main server and proxy server are not same. One uses TLS1.2 and other is TLS1.1. So i'm thinking about may this configuration lead to handshake failure cause my request will do not know to handshake with which version! This is my guess and asked the network admin already : "Why we have two different confines for server and proxy!" I'm waitings for their response. If you have any idea please feel free to add comment or post any answer.

解决方案

After strugle with many thing from client side, backed team set a valid certificate that make my problem solved. I mean they did not use self-sigend certificate but they used an invalid certificate! That is why i got hand shake error and in browser we can passed this error by accept responcibility of danger and click proceed button.

So if you see the same problem: Handshake error but you can proceed it in browser with my situation lets chech SSL certificate first to save time!

这篇关于通过OkHttp代理通过Https握手错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆