Android Https web service communication (SSL / TLS 1.2)

后端 未结 2 841
粉色の甜心
粉色の甜心 2021-02-09 06:27

In my Android application I\'ve got to communicate with a https web service and read the response.

I\'ve informed the server configured SSL with

相关标签:
2条回答
  • 2021-02-09 06:58

    According to the Android Developer documentation TLS 1.2 is available and enabled on devices with API level 20+ (Android 4.4 Wearable):

    http://developer.android.com/reference/javax/net/ssl/SSLEngine.html

    I assume non of your test devices uses that API level therefore you got the result that only 5.0 devices can connect.

    My personal experience is that some 4.4 devices support TLS 1.2 however it is not enabled. You can try to enable it by calling setEnabledProtocols(new String[]{"TLSv1.2"}) on the used SSLSocket.

    An elegant solution doing so is implementing an own SSLSocketFactory using the Proxy pattern:

    public class MySSLSocketFactory extends SSLSocketFactory {
    
        SSLSocketFactory sslSocketFactory;
    
        public MySSLSocketFactory(SSLSocketFactory sslSocketFactory) {
            super();
            this.sslSocketFactory = sslSocketFactory;
        }
    
        @Override
        public String[] getDefaultCipherSuites() {
            return sslSocketFactory.getDefaultCipherSuites();
        }
    
        @Override
        public String[] getSupportedCipherSuites() {
            return sslSocketFactory.getSupportedCipherSuites();
        }
    
        @Override
        public SSLSocket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
            SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(s, host, port, autoClose);
            socket.setEnabledProtocols(new String[] { "TLSv1.2" });
            return socket;
        }
    
        @Override
        public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
            SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(host, port);
            socket.setEnabledProtocols(new String[] { "TLSv1.2" });
            return socket;
        }
    
        @Override
        public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException,
                UnknownHostException {
            SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(host, port, localHost, localPort);
            socket.setEnabledProtocols(new String[] { "TLSv1.2" });
            return socket;
        }
    
        @Override
        public Socket createSocket(InetAddress host, int port) throws IOException {
            SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(host, port);
            socket.setEnabledProtocols(new String[] { "TLSv1.2" });
            return socket;
        }
    
        @Override
        public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
                throws IOException {
            SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(address, port, localAddress, localPort);
            socket.setEnabledProtocols(new String[] { "TLSv1.2" });
            return socket;
        }
    

    You can use it this way:

        ...
        urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(new MySSLSocketFactory(urlConnection.getSSLSocketFactory()));
        ...
    
    0 讨论(0)
  • 2021-02-09 07:15

    Here is a Kotlin version of the answer from Robert, which fixed the problem in my case:

    import java.net.InetAddress
    import java.net.Socket
    import javax.net.ssl.SSLSocket
    import javax.net.ssl.SSLSocketFactory
    
    class MySSLSocketFactory(socket_factory :SSLSocketFactory):
          SSLSocketFactory()
    {
        val sslSocketFactory :SSLSocketFactory
    
        init
        {
            this.sslSocketFactory = socket_factory
        }
    
        override fun getDefaultCipherSuites(): Array<String>
        {
            return this.sslSocketFactory.getDefaultCipherSuites()
        }
    
        override fun createSocket(socket: Socket?, host: String?, port: Int, autoclose: Boolean): Socket
        {
            val socket: SSLSocket = this.sslSocketFactory.createSocket(socket, host, port, autoclose) as SSLSocket
            socket.setEnabledProtocols(arrayOf("TLSv1.2"))
            return socket
        }
    
        override fun createSocket(host: String?, port: Int): Socket
        {
            val socket: SSLSocket = this.sslSocketFactory.createSocket(host, port) as SSLSocket
            socket.setEnabledProtocols(arrayOf("TLSv1.2"))
            return socket
        }
    
        override fun createSocket(host: String?, port: Int, local_host: InetAddress?, local_port: Int): Socket {
            val socket = sslSocketFactory.createSocket(host, port, local_host, local_port) as SSLSocket
            socket.enabledProtocols = arrayOf("TLSv1.2")
            return socket
        }
    
        override fun createSocket(host: InetAddress?, port: Int): Socket
        {
            val socket = sslSocketFactory.createSocket(host, port) as SSLSocket
            socket.enabledProtocols = arrayOf("TLSv1.2")
            return socket
        }
    
        override fun createSocket(address: InetAddress?, port: Int, local_address: InetAddress?, local_port: Int): Socket
        {
            val socket = sslSocketFactory.createSocket(address, port, local_address, local_port) as SSLSocket
            socket.enabledProtocols = arrayOf("TLSv1.2")
            return socket
        }
    
        override fun getSupportedCipherSuites(): Array<String>
        {
            return this.sslSocketFactory.getSupportedCipherSuites()
        }
    }
    
    0 讨论(0)
提交回复
热议问题