Skip to content Skip to sidebar Skip to footer

Tls Connection Using Sslsocket Is Slow In Android Os

I'm developing an Android app which uses SSLSocket to connect to a server. This is the code I'm using: // Connect if (socket == null || socket.isClosed() || !socket.isConnected())

Solution 1:

There was a bug on earlier versions of the Android SDK. Apparently, it's doing an unnecessary DNS reverse lookup. You need to prevent this from happening. Here's a workaround that worked for me. It used to take 15 seconds, now it takes 0-1 seconds. Hope it helps.

Here's the link to the Google issue.

booleanconnected=false;
if (socket == null || socket.isClosed() || !socket.isConnected()) {
    if (socket != null && !socket.isClosed()) {
        socket.close();
    }

    Log.i(getClass().toString(), "Connecting...");
    messages.getText().append("Connecting...");
    finalKeyStorekeyStore= KeyStore.getInstance("BKS");
    keyStore.load(getResources().openRawResource(R.raw.serverkey), null);

    finalKeyManagerFactorykeyManager= KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManager.init(keyStore, null);
    //keyManager.init(null, null);finalTrustManagerFactorytrustFactory= TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustFactory.init(keyStore);

    sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keyManager.getKeyManagers(), trustFactory.getTrustManagers(), rnd);
    finalSSLSocketFactorydelegate= sslContext.getSocketFactory();
    SocketFactoryfactory=newSSLSocketFactory() {
        @Overridepublic Socket createSocket(String host, int port)throws IOException, UnknownHostException {

            InetAddressaddr= InetAddress.getByName(host);
            injectHostname(addr, host);
            return delegate.createSocket(addr, port);
        }
        @Overridepublic Socket createSocket(InetAddress host, int port)throws IOException {

            return delegate.createSocket(host, port);
        }
        @Overridepublic Socket createSocket(String host, int port, InetAddress localHost, int localPort)throws IOException, UnknownHostException {

            return delegate.createSocket(host, port, localHost, localPort);
        }
        @Overridepublic Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException {

            return delegate.createSocket(address, port, localAddress, localPort);
        }
        privatevoidinjectHostname(InetAddress address, String host) {
            try {
                Fieldfield= InetAddress.class.getDeclaredField("hostName");
                field.setAccessible(true);
                field.set(address, host);
            } catch (Exception ignored) {
            }
        }
        @Overridepublic Socket createSocket(Socket s, String host, int port, boolean autoClose)throws IOException {

            injectHostname(s.getInetAddress(), host);
            return delegate.createSocket(s, host, port, autoClose);
        }
        @Overridepublic String[] getDefaultCipherSuites() {
            return delegate.getDefaultCipherSuites();
        }
        @Overridepublic String[] getSupportedCipherSuites() {
            return delegate.getSupportedCipherSuites();
        }
    };
    socket = (SSLSocket)factory.createSocket("192.168.197.133", 9999);
    socket.setSoTimeout(20000);
    socket.setUseClientMode(true);
    connected = true;
    Log.i(getClass().toString(), "Connected.");
    messages.getText().append("Connected.");
}

// Secureif (connected) {
    Log.i(getClass().toString(), "Securing...");
    messages.getText().append("Securing...");
    SSLSessionsession= socket.getSession();
    booleansecured= session.isValid();
    if (secured) {
        Log.i(getClass().toString(), "Secured.");
        messages.getText().append("Secured.");
    }
}

Solution 2:

You are using a new SecureRandom per connection, instead of using a single static pre-initialized SecureRandom. Everytime you create a new SecureRandom(), you need to gather entropy for seeding (a slow process).

SecureRandom does not self-seed until it is first used, which is why the delay does not occur until the call to getSession()

Solution 3:

I have done something similar to this and it is slower than an unsecured connection. Granted my case was https vs http and it is a little different the SSL/TLS factor will add slowness to the deal.

I have two identical apps that comunicate with the same protocol to the same server, one in android and one in iPhone, both using https. When I tested them both in http I would see more or less the same response time, in https iOS was slightly faster in my case, but not terribly.

Solution 4:

The problem is most likely in the way the device validates server certificates. Validation can involve contacting third-party for CRLs and OCSP responses. If this happens, it takes time. iPhone probably just doesn't do this (at least by default) which is a security hole BTW.

Post a Comment for "Tls Connection Using Sslsocket Is Slow In Android Os"