Skip to content Skip to sidebar Skip to footer

Android Https Web Service Communication (ssl / Tls 1.2)

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 TLS 1.2. I am using the following sa

Solution 1:

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:

publicclassMySSLSocketFactoryextendsSSLSocketFactory {

    SSLSocketFactory sslSocketFactory;

    publicMySSLSocketFactory(SSLSocketFactory sslSocketFactory) {
        super();
        this.sslSocketFactory = sslSocketFactory;
    }

    @Overridepublic String[] getDefaultCipherSuites() {
        return sslSocketFactory.getDefaultCipherSuites();
    }

    @Overridepublic String[] getSupportedCipherSuites() {
        return sslSocketFactory.getSupportedCipherSuites();
    }

    @Overridepublic SSLSocket createSocket(Socket s, String host, int port, boolean autoClose)throws IOException {
        SSLSocketsocket= (SSLSocket) sslSocketFactory.createSocket(s, host, port, autoClose);
        socket.setEnabledProtocols(newString[] { "TLSv1.2" });
        return socket;
    }

    @Overridepublic Socket createSocket(String host, int port)throws IOException, UnknownHostException {
        SSLSocketsocket= (SSLSocket) sslSocketFactory.createSocket(host, port);
        socket.setEnabledProtocols(newString[] { "TLSv1.2" });
        return socket;
    }

    @Overridepublic Socket createSocket(String host, int port, InetAddress localHost, int localPort)throws IOException,
            UnknownHostException {
        SSLSocketsocket= (SSLSocket) sslSocketFactory.createSocket(host, port, localHost, localPort);
        socket.setEnabledProtocols(newString[] { "TLSv1.2" });
        return socket;
    }

    @Overridepublic Socket createSocket(InetAddress host, int port)throws IOException {
        SSLSocketsocket= (SSLSocket) sslSocketFactory.createSocket(host, port);
        socket.setEnabledProtocols(newString[] { "TLSv1.2" });
        return socket;
    }

    @Overridepublic Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException {
        SSLSocketsocket= (SSLSocket) sslSocketFactory.createSocket(address, port, localAddress, localPort);
        socket.setEnabledProtocols(newString[] { "TLSv1.2" });
        return socket;
    }

You can use it this way:

    ...
    urlConnection = (HttpsURLConnection) url.openConnection();
    urlConnection.setSSLSocketFactory(newMySSLSocketFactory(urlConnection.getSSLSocketFactory()));
    ...

Solution 2:

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

classMySSLSocketFactory(socket_factory :SSLSocketFactory):
      SSLSocketFactory()
{
    val sslSocketFactory :SSLSocketFactory

    init
    {
        this.sslSocketFactory = socket_factory
    }

    overridefungetDefaultCipherSuites(): Array<String>
    {
        returnthis.sslSocketFactory.getDefaultCipherSuites()
    }

    overridefuncreateSocket(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
    }

    overridefuncreateSocket(host: String?, port: Int): Socket
    {
        val socket: SSLSocket = this.sslSocketFactory.createSocket(host, port) as SSLSocket
        socket.setEnabledProtocols(arrayOf("TLSv1.2"))
        return socket
    }

    overridefuncreateSocket(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
    }

    overridefuncreateSocket(host: InetAddress?, port: Int): Socket
    {
        val socket = sslSocketFactory.createSocket(host, port) as SSLSocket
        socket.enabledProtocols = arrayOf("TLSv1.2")
        return socket
    }

    overridefuncreateSocket(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
    }

    overridefungetSupportedCipherSuites(): Array<String>
    {
        returnthis.sslSocketFactory.getSupportedCipherSuites()
    }
}

Post a Comment for "Android Https Web Service Communication (ssl / Tls 1.2)"