通过OkHttp代理通过Https握手错误 [英] Https through proxy with OkHttp got handshake error
问题描述
我将使用需要配置 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屋!