amitshekhariitbhu / Fast-Android-Networking

🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀
https://outcomeschool.com
Apache License 2.0
5.67k stars 955 forks source link

javax.net.ssl.SSLHandshakeException: Handshake failed #297

Open Joeeeyy opened 6 years ago

Joeeeyy commented 6 years ago

I am trying to call pixabay api and I'm getting this error. com.androidnetworking.error.ANError: javax.net.ssl.SSLHandshakeException: Handshake failed Can you help me solve this? I have done some research and found it's related to https and ssl security, but nothing I understand from those materials.

rakave commented 5 years ago

@Joeeeyy Try this :

1) Go to https://www.ssllabs.com and check your domain name to see what Ciphersuites your server is using. Configuration - > Cipher Suites (i.e TLS 1.2 / TLS 1.1 ,etc). Then check the "Handshake Simulation" info as well to understand compatibility for each Android version.

2) If you are using nginx for your backend, add the following lines to your ssl-params config

ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";

3) For the Frontend, use unsafeOkhttp but include all the ciphersuites that your server supports. This is my configuration as an example:

private static OkHttpClient myUnsafeHttpClient() {

    try {

        // Create a trust manager that does not validate certificate chains
        final TrustManager[] trustAllCerts = new TrustManager[] {

                new X509TrustManager() {

                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) { }
                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                    }
                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                }
        };

        //Using TLS 1_2 & 1_1 for HTTP/2 Server requests
        // Note : The following is suitable for my Server. Please change accordingly
        ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
                .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0)
                .cipherSuites(
                        CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
                        CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
                        CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                        CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
                        CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
                        CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
                        CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
                        CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                        CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
                        CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
                        CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
                .build();

        // Install the all-trusting trust manager
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        // Create an ssl socket factory with our all-trusting manager
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory);
        builder.connectionSpecs(Collections.singletonList(spec));
        builder.hostnameVerifier((hostname, session) -> true);
        return builder.build();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

4) Initialize Androidnetworking as follows :

AndroidNetworking.initialize(getApplicationContext(), myUnsafeHttpClient());

This worked for me after a Week of struggle.....Hope it helps anyone in need!

ddopik commented 4 years ago

it works thank you @rakave

niravtopsy commented 4 years ago

@amitshekhariitbhu i upload one app with TrustManager[] trustAllCerts but its rejected by google play store, So, I think it not final solutions.

RahulGupta2312 commented 4 years ago

@amitshekhariitbhu i upload one app with TrustManager[] trustAllCerts but its rejected by google play store, So, I think it not final solutions.

Google doesn't approve apps with Trust All Anchor code. Please remove it from your code. And get SSL from a verified provider, and setup on your server.

m-irfan commented 4 years ago

Check your android device's date and time

Jackyto commented 4 months ago

Saved my day, thank you @rakave !