Purushotam Kumar
Purushotam Kumar

Reputation: 11

Retrofit gives SSLHandshakeException

I am using Retrofit in my Android App. When I make request with 'https://example.com' as the base url it works fine. But when I make request with 'https://www.example.com' as a base url It gives SSLHandshakeException. I am not understanding why it is happening.

Upvotes: 1

Views: 3361

Answers (2)

Dilip
Dilip

Reputation: 2734

I have used it with 2.2.0

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) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {

                    }

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                   }
                }
        };

        // Install the all-trusting trust manager

        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.interceptors().add(httpLoggingInterceptor);
        client.readTimeout(180, TimeUnit.SECONDS);
        client.connectTimeout(180, TimeUnit.SECONDS);

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
       keyStore.load(null, null);

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

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
       trustManagerFactory.init(keyStore);
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, "keystore_pass".toCharArray());
        sslContext.init(null, trustAllCerts, new SecureRandom());
        client.sslSocketFactory(sslContext.getSocketFactory())
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
               });

        Gson gson = new GsonBuilder().setLenient().create();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Common.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client.build())
                .build();

        serviceApi = retrofit.create(Api.class);

thanks hope this will help you. Sometime ssl version 1.2 or lower not installed in server side as well.

Upvotes: 1

Gowtham Subramaniam
Gowtham Subramaniam

Reputation: 3478

OkHttp has removed support for obsolete HTTPS configurations and the host you’re trying to reach needs to be updated.

If you don't want to do that you can configure cipher suites and TLS versions in OkHttp to support this obsolete server.

https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CustomCipherSuites.java

From my understanding this will ensure that all the overlapped CipherSuites are used. Here are the results I got from testing it on different Android versions:

OkHttp 2.3.0

5.1 - working
5.0 - working
4.4.4 - error
4.3 - error
4.2.2 - error
4.1.1 - error
4.0 - error

OkHttp 2.2.0

5.1 - working
5.0 - working
4.4.4 - working
4.3 - working
4.2.2 - working
4.1.1 - working
4.0 - error

Upvotes: 0

Related Questions