Skip to content

Instantly share code, notes, and snippets.

@fkrauthan
Last active January 7, 2023 04:09
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save fkrauthan/ac8624466a4dee4fd02f to your computer and use it in GitHub Desktop.
Save fkrauthan/ac8624466a4dee4fd02f to your computer and use it in GitHub Desktop.
Custom SSLSocketFactory Implementation to enable tls 1.1 and tls 1.2 for android 4.1 (16+)
package net.cogindo.ssl;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/**
* @author fkrauthan
*/
public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}
@fkrauthan
Copy link
Author

@Prosanto
Copy link

Hi @fkrauthan,

I face this issues(android enable tls).But i can't solve this .I am try to implement your example.But can't understand how i will add this code
http://imgur.com/HQZ4XRo

`public class SSLSocketFactoryEx extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");

public SSLSocketFactoryEx(KeyStore truststore)
        throws NoSuchAlgorithmException, KeyManagementException,
        KeyStoreException, UnrecoverableKeyException {
    super(truststore);

    TrustManager tm = new X509TrustManager() {

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] chain, String authType)
                throws java.security.cert.CertificateException {

        }

        @Override
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] chain, String authType)
                throws java.security.cert.CertificateException {

        }
    };

    sslContext.init(null, new TrustManager[]{tm}, null);
}

@Override
public Socket createSocket(Socket socket, String host, int port,
        boolean autoClose) throws IOException, UnknownHostException {
    return sslContext.getSocketFactory().createSocket(socket, host, port,
            autoClose);
}

@Override
public Socket createSocket() throws IOException {
    return sslContext.getSocketFactory().createSocket();
}

}
`

@mtcstle
Copy link

mtcstle commented Jun 6, 2016

Prosanto, have you made any progress here. You're starting out way ahead of me. Can you send me or point me to any directions on how to add code to a phone. Can this sort of testing be done on a emulator? We're trying to restrict our web server to TLS v1.2 or better and it's breaking the mail client on Android 4 phones.
mtcstle

@seyoung-hyun
Copy link

Hi @fkrauthan,
Can I use your code in my commercial app?
Please let me know how I can use the code for commercial distribution.
Thanks.

@cantek41
Copy link

cantek41 commented Apr 2, 2017

SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
TrustManager[] trustManagers = new TrustManager[] { new TrustManagerManipulator() };
sslContext.init(null, trustManagers, new SecureRandom());
SSLSocketFactory noSSLv3Factory = new TLSSocketFactory(sslContext.getSocketFactory());
urlConnection.setSSLSocketFactory(noSSLv3Factory);
https://github.com/IKANOW/Infinit.e/blob/master/core/infinit.e.data_model/src/com/ikanow/infinit/e/data_model/utils/TrustManagerManipulator.java

@SahilKashyap
Copy link

SahilKashyap commented Apr 21, 2017

thanks, this code works for me but now Google Play Store rejected my application due to Malicious Behavior. Before adding this code my application uploaded successfully on Play Store. So, Please provide another solution.

@ishantsagar
Copy link

@SahilKashyap did you get another way of doing it, since your app was rejected by play store? I need to enable TLS 1.2 support for my apps having API 16+

@tamilanmanikandan
Copy link

How to implement these SSLSocketFactory to webview in android?

@derek1287
Copy link

derek1287 commented Jun 20, 2018

You maniac, this code solves my issue EXACTLY. Thank you!!!

@batica81
Copy link

batica81 commented Aug 4, 2018

Works on API 19! You are a genius!

@Kishanjvaghela
Copy link

@dharmakshetri
Copy link

dharmakshetri commented Mar 19, 2019

i am using httpclient and using above TLSSocketFactory , and calling by getting httpclient and only display tlsv1.0, but i only need to use tlsv1.2, Could you please help where i am doing wrong.
TLSSocketFactoryNew .java

public class TLSSocketFactoryNew extends SSLSocketFactory {

    private SSLSocketFactory internalSSLSocketFactory;
    

    public TLSSocketFactoryNew(SSLSocketFactory socketFactory) {
        internalSSLSocketFactory=socketFactory;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return internalSSLSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return internalSSLSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
    }

    /*
     * Utility methods
     */

    private static Socket enableTLSOnSocket(Socket socket) {
        if (socket != null && (socket instanceof SSLSocket)
                && isTLSServerEnabled((SSLSocket) socket)) { // skip the fix if server doesn't provide there TLS version
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
        }
        return socket;
    }

    private static boolean isTLSServerEnabled(SSLSocket sslSocket) {
        System.out.println("isTLSServerEnabled :: " + sslSocket.getSupportedProtocols().toString());
        for (String protocol : sslSocket.getSupportedProtocols()) {
            if (protocol.equals("TLSv1.2")) {
                return true;
            }
        }
        return false;
    }
}

Getting httpclient in httppost method to execute httpclient.

private CloseableHttpClient getNewClient() {
    CloseableHttpClient httpclient=null;
    SSLContext sslContext = null ;
    try {
      sslContext = SSLContext.getInstance("TLSv1.2");
      TrustManager[] trustManagers = new TrustManager[] { new TrustManagerManipulator() };
      sslContext.init(null, trustManagers, new SecureRandom());
      SSLSocketFactory sslSocketFactory = new TLSSocketFactoryNew(sslContext.getSocketFactory());
      httpclient = HttpClients.custom()
              .setSSLSocketFactory((LayeredConnectionSocketFactory) sslSocketFactory)
              .build();

    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (KeyManagementException e) {
      e.printStackTrace();
    }

    return httpclient;
  }

Min Api : 19

compile files('libs/httpclient-4.5.5.jar')  
compile files('libs/httpcore-4.4.11.jar'):

Thanks.

@derleyogita
Copy link

Thanks, Works on API 19!

@jdavidag
Copy link

alguien sabe como o donde se coloca el conscrypt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment