低版本https握手失败
- 错误
- 查看接口的协议
- 改写代码(网络访问采用原生的HttpsURLConnection)
参考博文:
https://www.cnblogs.com/lwbqqyumidi/p/12063489.html
https://blog.csdn.net/qq_16117167/article/details/52621112
错误
如图所示,访问接口的时候,错误写着sslv3报握手错误,然后查了网上的说法就是协议不对,因为低版本的默认用的协议是ssl3之类的协议。但是它其实支持TLS1.1或者TLS1.2的,只是需要手动去写。
查看接口的协议
测试网址:https://www.ssllabs.com/ssltest/index.html
这个网页里面,把接口的地址放进去分析
分析结果:
所以确实是不支持的,支持TLS1.1,TLS1.2之类的协议。
改写代码(网络访问采用原生的HttpsURLConnection)
最主要的是sslSocketFactory改写,改写这个的话就要重写SSLSocketFactory。
package com.rengda.sigangapp
import java.net.InetAddress
import java.net.Socket
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager
class MySSLSocketFactory(): SSLSocketFactory() {
var internalSSLSocketFactory:SSLSocketFactory
var context: SSLContext
init {
context = SSLContext.getInstance("TLSv1.1")
context.init(null, null, null)
internalSSLSocketFactory=context.socketFactory
}
override fun getDefaultCipherSuites(): Array<String> {
return internalSSLSocketFactory.getDefaultCipherSuites()
}
override fun createSocket(s: Socket?, host: String?, port: Int, autoClose: Boolean): Socket {
val sslSocket=context?.getSocketFactory()?.createSocket(s, host, port, autoClose) as SSLSocket
sslSocket.setEnabledProtocols(arrayOf("TLSv1.2","TLSv1.1"))
return sslSocket;
}
override fun getSupportedCipherSuites(): Array<String> {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
override fun createSocket(): Socket {
return super.createSocket()
}
override fun createSocket(host: String?, port: Int): Socket {
val sslSocket=context?.getSocketFactory()?.createSocket( host, port) as SSLSocket
sslSocket.setEnabledProtocols(arrayOf("TLSv1.2","TLSv1.1"))
return sslSocket;
}
override fun createSocket(host: String?, port: Int, localHost: InetAddress?, localPort: Int): Socket {
val sslSocket=context?.getSocketFactory()?.createSocket(host, port, localHost, localPort) as SSLSocket
sslSocket.setEnabledProtocols(arrayOf("TLSv1.2","TLSv1.1"))
return sslSocket;
}
override fun createSocket(host: InetAddress?, port: Int): Socket {
val sslSocket=context?.getSocketFactory()?.createSocket(host, port) as SSLSocket
sslSocket.setEnabledProtocols(arrayOf("TLSv1.2","TLSv1.1"))
return sslSocket;
}
override fun createSocket(address: InetAddress?, port: Int, localAddress: InetAddress?, localPort: Int): Socket {
val sslSocket=context?.getSocketFactory()?.createSocket(address, port, localAddress, localPort) as SSLSocket
sslSocket.setEnabledProtocols(arrayOf("TLSv1.2","TLSv1.1"))
return sslSocket;
}
}
在用HttpsURLConnection的地方用自己的SSLSocketFactory,片段代码如下 connection.sslSocketFactory= MySSLSocketFactory() 这句就是关键。
var connection: HttpsURLConnection? = null
val url = URL(url)
connection = url.openConnection() as HttpsURLConnection
connection.connectTimeout = 10000
connection.readTimeout = 10000
connection.requestMethod = "GET"
connection.sslSocketFactory= MySSLSocketFactory()
这样之后就可以访问了