安卓4.X版本ssl: sslv3 alert handshake failure 握手失败

低版本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的,只是需要手动去写。
安卓4.X版本ssl: sslv3 alert handshake failure 握手失败_第1张图片

查看接口的协议

测试网址:https://www.ssllabs.com/ssltest/index.html
这个网页里面,把接口的地址放进去分析
分析结果:
安卓4.X版本ssl: sslv3 alert handshake failure 握手失败_第2张图片
所以确实是不支持的,支持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 {
        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 {
        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()

这样之后就可以访问了

你可能感兴趣的:(Kotlin,Android,android,kotlin)