Android HttpsUrlConnection javax.net.ssl.SSLException Connection closed by peer handshake error when using local truststore

烂漫一生 提交于 2019-11-29 22:39:33

I solved my problem - I needed to use a certificate with 10.0.2.2 as the common name (CN) so it matched Android localhost ip address of 10.0.2.2 instead of 'localhost' or '127.0.0.1'.

Edit: you could probably create a certificate with localhost as the CN and '127.0.0.1' and '10.0.2.2' as Subject Alternative Names (SAN).

Once I created 10.0.2.2 cert and private key pem files, I was able to hit my server running with the following command:

openssl s_server -accept 8888 -cert 10.0.2.2-cert.pem -key 10.0.2.2-key.pem  -state -www

If you want to force the client to provide a certificate (though it won't be checked), add the flag -Verify 1 to the command above.

To test the server at the command line you can use the following (note openssl is able to connect via 127.0.0.1):

openssl s_client -connect 127.0.0.1:8888

And to add a client cert if the server requires it, add the flags -cert client-cert.pem -key client-key.pem

In my Android client I used the following code to connect (error checking removed):

// use local trust store (CA)
TrustManagerFactory tmf;
KeyStore trustedStore = null;
InputStream in = context.getResources().openRawResource(R.raw.mycatruststore); // BKS in res/raw
trustedStore = KeyStore.getInstance("BKS");
trustedStore.load(in, "insertBksPasswordHere".toCharArray());
tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustedStore);

// load client certificate
KeyStore clientKeyStore = loadClientKeyStore(getApplicationContext());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(clientKeyStore, "insertPasswordHere".toCharArray());

SSLContext context = SSLContext.getInstance("TLS");

// provide client cert - if server requires client cert this will pass
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;

// connect to url
URL u = new URL("https://10.0.2.2:8888/");
HttpsURLConnection urlConnection = (HttpsURLConnection) u.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.connect();
System.out.println("Response Code: " + urlConnection.getResponseCode());

You should get a response code of 200, and can dissect the response from there.

Here's the code to load the client credentials, which is identical to loading the server key store but with a different resource filename and password:

private KeyStore loadClientKeyStore(Context context) {
    InputStream in = context.getResources().openRawResource(R.yourKeyStoreFile);
    KeyStore trusted = null;
    trusted = KeyStore.getInstance("BKS");
    trusted.load(in, "yourClientPassword".toCharArray());
    in.close();
    return trusted;
}

I wasted my 6 - 7 hours fixed this problem and finally it worked with

public void URLConnection(String webUrl) throws IOException, NoSuchAlgorithmException, KeyManagementException {
        //TLSSocketFactory objTlsSocketFactory = new TLSSocketFactory();
        URL url = new URL(webUrl);
        HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
        urlConnection.setRequestMethod("GET");
        //urlConnection.setSSLSocketFactory(objTlsSocketFactory);

        int responseCode = urlConnection.getResponseCode();
        System.out.println("\nSending 'GET' request to URL : " + url);
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(urlConnection.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        //print result
        System.out.println(response.toString());
    }

And it worked !!!!!!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!