-1

I have been using the approach with a custom trust manager to avoid SSL handshake exceptions

static {
        try {
                SSLContext ctx = SSLContext.getInstance("TLS");
                ctx.init(null, new TrustManager[]{
                        new X509TrustManager() {
                                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                                }

                                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                                }

                                public X509Certificate[] getAcceptedIssuers() {
                                        return new X509Certificate[]{};
                                }
                        }
                }, null);

        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
                e.printStackTrace();
        }

        HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
}

and then using JSoup to get the page contents:

Document document = Jsoup.connect(url).timeout(TIMEOUT).userAgent(USER_AGENT_MOZILLA).get();

But recently I ran against an url on which that approach didn't work.

http://feeds.dzone.com/link/18931/15381195/what-are-microservices-2

I got that exception again

Interesting that running that code in a JUnit test doesn't cause any problems. I assume it's because the corresponding certificate is available on my PC. But if I run the Android app with that code, be it physical device or emulator the exception would be thrown. I can also open the url in the browser on physical device or emulator.

Any ideas why the approach fails on that url?

Below is the output ( e.printStackTrace() )

W/System.err: javax.net.ssl.SSLHandshakeException: Handshake failed
W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429)
W/System.err:     at com.android.okhttp.Connection.connectTls(Connection.java:235)
        at com.android.okhttp.Connection.connectSocket(Connection.java:199)
        at com.android.okhttp.Connection.connect(Connection.java:172)
        at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:367)
        at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:130)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:246)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:126)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java)
        at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:732)
        at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:759)
        at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:707)
W/System.err:     at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:297)
        at org.jsoup.helper.HttpConnection.get(HttpConnection.java:286)
        at com.denis.aristov.tts.web.DZoneProcessor.extractPlainText(DZoneProcessor.java:69)
        at com.denis.aristov.tts.web.WebContentProcessor.lambda$buildRequests$0(WebContentProcessor.java:177)
        at com.denis.aristov.tts.web.-$$Lambda$WebContentProcessor$pTY0-1VHYsJSt_VDuccv_skDjX4.call(lambda)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
        Suppressed: javax.net.ssl.SSLHandshakeException: Handshake failed
            ... 24 more
W/System.err:       Suppressed: javax.net.ssl.SSLHandshakeException: Handshake failed
                ... 24 more
            Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xa29cf980: Failure in SSL library, usually a protocol error
    error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (external/boringssl/src/ssl/s3_pkt.c:610 0x8f555da0:0x00000001)
    error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (external/boringssl/src/ssl/s3_clnt.c:764 0xa0030266:0x00000000)
W/System.err:     at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
                ... 23 more
        Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xa29cf980: Failure in SSL library, usually a protocol error
    error:1000043e:SSL routines:OPENSSL_internal:TLSV1_ALERT_INAPPROPRIATE_FALLBACK (external/boringssl/src/ssl/s3_pkt.c:610 0x8f555e00:0x00000001)
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
            ... 23 more
    Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xa29cf980: Failure in SSL library, usually a protocol error
    error:1000043e:SSL routines:OPENSSL_internal:TLSV1_ALERT_INAPPROPRIATE_FALLBACK (external/boringssl/src/ssl/s3_pkt.c:610 0x8f555e00:0x00000001)
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
        ... 23 more

I'm using Android 7 (API Level 27)

I used the site https://www.ssllabs.com/ssltest/ to scan the SSL server and it reported:

This server supports TLS 1.0 and TLS 1.1. Grade capped to B.

This server supports TLS 1.3.

However the site suggested me to scan not the original hostname feeds.dzone.com but feedpress.me (because of redirection perhaps)

ka3ak
  • 2,435
  • 2
  • 30
  • 57
  • You got what exception again? You haven't reported an actual problem here. – user207421 Jun 30 '22 at 07:53
  • @user207421 I've appended the stack trace to the question – ka3ak Jun 30 '22 at 08:04
  • 1
    This isn't anything to do with certificates. You shouldn't think that radically insecure `TrustManagers` are a solution to everything. In reality they aren't a solution to anything. – user207421 Jun 30 '22 at 08:32
  • 1
    An SSL/TLS handshake can fail because of many reasons just disabling certificate validation is a bad idea. Often the server or client do not match or are configured in a way that they don't have a cipher in common. What Android device is used (Android version) and what server is used? Test the server for provided TLS versions and ciphers: https://www.ssllabs.com/ssltest/ – Robert Jun 30 '22 at 09:15
  • The URL `feeds.dzone.com` redirects to `https://dzone.com/pages/feeds` so I would use that URL to avoid problems. – Robert Jul 01 '22 at 10:23
  • @Robert Thanks for tip. I noticed that the original URL transformed to https://dzone.com/articles/what-are-microservices-2 when I opened it in a browser. So I finally decided to use a dirty workaround in my app by replacing everything in the original URL except the last part - what-are-microservices-2 and it started to work without any manipulations with custom trust manager etc. – ka3ak Jul 01 '22 at 14:41

1 Answers1

-2
Try this 


static {
        try {
                SSLContext ctx = SSLContext.getInstance("TLS");
                ctx.init(null, new TrustManager[]{
                        new X509TrustManager() {
                                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                                }

                                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                                }

                                public X509Certificate[] getAcceptedIssuers() {
                                        new java.security.cert.X509Certificate[]{};
                                }
                        }
                }, new java.security.SecureRandom());

        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
                e.printStackTrace();
        }

        HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
}
  • new java.security.SecureRandom() instead of null ? Unfortunately it doesn't make any difference – ka3ak Jun 30 '22 at 07:46
  • 1
    Try it why? What reason do you have for thinking this will fix it? Mere code is not an answer. You have to explain. In this case you are merely repeating what happens anyway if you supplied null. – user207421 Jun 30 '22 at 07:54