Android Client / Server on TLS v1.2

2019-03-10 20:50发布

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 :(

标签: java android ssl
1条回答
家丑人穷心不美
2楼-- · 2019-03-10 21:13

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;
    }

    ...
}
查看更多
登录 后发表回答