0

I am calling a api from android 4.4 version device which has only TLSV1.2 support, you can check here. So if i am adding certificates in request it is working fine but API does not need any certificates so without certificates it is throwing

unable to find acceptable protocol exception.

I have tried enabling TLSV1.2 using below code:

ConnectionSpec requireTls12 = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                .tlsVersions(TlsVersion.TLS_1_2)
                .build();
        OkHttpClient client = new OkHttpClient.Builder()
                .connectionSpecs(Arrays.asList(requireTls12))
                .build();

        return client.newBuilder().build();

and all other solutions

i can not use ProviderInstaller from Google Play Services to enable it, because my device does not have google play services installed.

this is the working code with client certificates:

CertificateFactory certificateFactory = null;
        Certificate certificate = null;
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        try {
            certificateFactory = CertificateFactory.getInstance("X.509");
            certificate = certificateFactory.generateCertificate(certInputStream);
            // Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", certificate);

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            // Create an SSLContext that uses our TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);

            //Initialize Interceptors
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);

            //Assign custom trusted ssl to builder
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            builder.sslSocketFactory(sslSocketFactory);
            builder.addInterceptor(loggingInterceptor);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } 

Can someone please suggest a workaround for this?

James Z
  • 12,209
  • 10
  • 24
  • 44
Android Priya
  • 686
  • 1
  • 6
  • 23
  • *"So if i am adding certificates in request it is working fine but API does not need any certificates so without certificates it is throwing unable to find acceptable protocol exception."* - I'm not sure what you mean with *"adding certificates in request"* (no code) but I assume you mean client certificates. If it works with client certificates but not without (and this is the only change) then the server obviously needs client certificates. But I recommend that you actually post not only the failing code but also the working code so it gets clear what the actual difference is. – Steffen Ullrich Jan 16 '20 at 17:51
  • yes i mean client certificates. Api guys are saying API does not need certificates, i am assuming its SSLhandshake problem for TLSV1.2 from the logs – Android Priya Jan 16 '20 at 18:21
  • A SSL handshake problems happens among others if the server requires client certificates but the client does not provide any. – Steffen Ullrich Jan 16 '20 at 18:31
  • @Steffen after adding above code to enable tlsv1.2 it is throwing exception :java.net.UnknownServiceException: Unable to find acceptable protocols. isFallback=false – Android Priya Jan 16 '20 at 18:33
  • Your working code does not use client certificates. It only sets a certificate as trusted (`ca`) although it later overrides the validation to accept anything though (no idea what you are trying to achieve here, probably you don't know either). The main difference is that the working client is not restricted to TLS 1.2 though but will also do TLS 1.0 and later. I would recommend to not restrict the TLS version in the client since it will use the best version support on both sides anyway. – Steffen Ullrich Jan 16 '20 at 18:41

0 Answers0