Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Client / Server on TLS v1.2

Tags:

java

android

ssl

I'm trying my to create TLS v1.2 communication between a server and android client. I established a TLS v1.0 connection with any problem, but I cannot get v1.2. This is server code:

char[] passphrase = "myComplexPass1".toCharArray();
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(new FileInputStream("cacerts"), passphrase);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keystore, passphrase);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
SSLContext sslContext.init(keyManagers, null, null);
SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(port);
sslServerSocket.setEnabledProtocols(new String [] { "TLSv1", "TLSv1.1", "TLSv1.2" });
sslServerSocket.setUseClientMode(false);
sslServerSocket.setWantClientAuth(false);
sslServerSocket.setNeedClientAuth(false);
sslSocket = (SSLSocket)sslServerSocket.accept();

while this is client code:

char[] passphrase = "myComplexPass1".toCharArray();
KeyStore keystore = KeyStore.getInstance("BKS");
keystore.load(this.getApplicationContext().getResources().openRawResource(R.raw.jb), passphrase);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore, passphrase);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
Log.d("Context Protocol",sslContext.getProtocol());//this prints correctly TLS v1.2!
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
TrustManager[] trustManagers = new TrustManager[]{
                    new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers()
                        {
                            return null;
                        }
                        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                        {

                        }
                        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                        {

                        }
                    }
            };
sslContext.init(keyManagers, trustManagers, new SecureRandom());
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) sslContext.getSocketFactory();
SSLSocket skt = (SSLSocket) sslSocketFactory.createSocket(HOST, PORT);
skt.setKeepAlive(true);

Client code, written in a java client running on JRE7 on my pc, perfectly works and I see with getProtocol (server-side) TLSv1.2 with a correct cipher, supported by tlsv1.2. Same code on android make a tlsv1.0 connection! I really don't uderstand. On Java client JRE7 works, on android ONLY tlsv1.0 Any suggestion?

It's my first question, I searched a lot. Probably my formatting is not correct :(

like image 931
Guido Davide Avatar asked Dec 05 '25 10:12

Guido Davide


1 Answers

Kind of late to be answering this, but maybe someone else will need an answer.

I have run into the same issue. No matter whether you provide TLSv1.2 to the SSLContext.init() method, some Android versions that I've tried do not enable TLS 1.2. You must enable that on your client socket using setEnabledProtocols() just as you do for your server socket. For me, I did this in a custom SSLSocketFactory I created:

public class MySSLSocketFactory extends SSLSocketFactory
                                throws NoSuchAlgorithmException {

    private SSLContext mSSLContext;

    public MySSLSocketFactory(KeyManager km) {
        ...
        mSSLContext = SSLContext.getInstance("TLSv1.2");
        ...
        mSSLContext.init(new KeyManager[] {km}, null, null);
        ...
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException {
        SSLSocket s = (SSLSocket)mSSLContext.getSocketFactory().createSocket(socket, host, port, autoClose);
        s.setEnabledProtocols(new String[] {"TLSv1.2"} );
        return s;
    }

    ...
}
like image 57
BJV Avatar answered Dec 08 '25 06:12

BJV



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!