3

I tried disable SSL verification in my app, but app crashes in Android 10 in some devices. I used in my app Retrofit and Okhttp. Here how I tried to disable SSL verification in my app. I didn't find any solution from the internet.

    class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val trustAllCerts = arrayOf<TrustManager>(
            object : X509TrustManager {
                override fun checkClientTrusted(
                    chain: Array<out X509Certificate>?,
                    authType: String?
                ) {

                }

                override fun checkServerTrusted(
                    chain: Array<out X509Certificate>?,
                    authType: String?
                ) {

                }

                override fun getAcceptedIssuers(): Array<X509Certificate>? {
                    return null
                }
            }
        )

        val sslContext = SSLContext.getInstance("SSL")
        sslContext.init(null, trustAllCerts, SecureRandom())
        val sslSocketFactory = sslContext.socketFactory

        val okhttp = OkHttpClient.Builder()
            .sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
            .build()

        val retrofit = Retrofit.Builder()
            .baseUrl("https://example.com")
            .client(okhttp)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(ScalarsConverterFactory.create())
            .build()

        val api = retrofit.create(Api::class.java)

        btn.setOnClickListener {
            api.loadMain()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe({

                }, {
                    Log.d("myLogs", it.message)
                })
        }
    }
}

In Android 10 I catch this exception

2020-02-07 14:25:43.552 11668-11668/com.example.okhttpexample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.okhttpexample, PID: 11668
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.okhttpexample/com.example.okhttpexample.MainActivity}: java.lang.IllegalArgumentException: Required method checkServerTrusted(X509Certificate[], String, String, String) missing
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
 Caused by: java.lang.IllegalArgumentException: Required method checkServerTrusted(X509Certificate[], String, String, String) missing
    at android.net.http.X509TrustManagerExtensions.<init>(X509TrustManagerExtensions.java:71)
    at okhttp3.internal.platform.android.Android10CertificateChainCleaner.<init>(Android10CertificateChainCleaner.kt:36)
    at okhttp3.internal.platform.Android10Platform.buildCertificateChainCleaner(Android10Platform.kt:62)
    at okhttp3.internal.tls.CertificateChainCleaner$Companion.get(CertificateChainCleaner.kt:42)
    at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.kt:735)
    at com.example.okhttpexample.MainActivity.onCreate(MainActivity.kt:56)
    at android.app.Activity.performCreate(Activity.java:7802)
    at android.app.Activity.performCreate(Activity.java:7791)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:214) 
    at android.app.ActivityThread.main(ActivityThread.java:7356) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

This exception from crashlytics. It also happens only in Android 10

       Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.okhttpexample/com.example.okhttpexample.MainActivity}: java.lang.IllegalStateException: Unable to extract the trust manager on a, sslSocketFactory is class com.android.org.conscrypt.OpenSSLSocketFactoryImpl
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3448)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
   at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
   at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147)
   at android.os.Handler.dispatchMessage(Handler.java:107)
   at android.os.Looper.loop(Looper.java:237)
   at android.app.ActivityThread.main(ActivityThread.java:7811)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)


   Caused by java.lang.IllegalStateException: Unable to extract the trust manager on a, sslSocketFactory is class com.android.org.conscrypt.OpenSSLSocketFactoryImpl
   at okhttp3.internal.platform.Platform.buildCertificateChainCleaner(Platform.java:151)
   at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.java:698)
   at com.example.okhttpexample.di.NetworkModule.provideOkHttpClient(NetworkModule.java:277)
   at com.example.okhttpexample.di.NetworkModule_ProvideOkHttpClientFactory.provideOkHttpClient(NetworkModule_ProvideOkHttpClientFactory.java:47)
   at com.example.okhttpexample.di.NetworkModule_ProvideOkHttpClientFactory.get(NetworkModule_ProvideOkHttpClientFactory.java:36)
   at com.example.okhttpexample.di.NetworkModule_ProvideOkHttpClientFactory.get(NetworkModule_ProvideOkHttpClientFactory.java:12)
   at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
   at com.example.okhttpexample.di.NetworkModule_ProvideRetrofitFactory.get(NetworkModule_ProvideRetrofitFactory.java:32)
   at com.example.okhttpexample.di.NetworkModule_ProvideRetrofitFactory.get(NetworkModule_ProvideRetrofitFactory.java:11)
   at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
   at com.example.okhttpexample.di.NetworkModule_ProvideVeonApiFactory.get(NetworkModule_ProvideVeonApiFactory.java:27)
   at com.example.okhttpexample.di.NetworkModule_ProvideVeonApiFactory.get(NetworkModule_ProvideVeonApiFactory.java:10)
   at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
   at com.example.okhttpexample.api.NetworkHelper_Factory.get(NetworkHelper_Factory.java:42)
   at com.example.okhttpexample.api.NetworkHelper_Factory.get(NetworkHelper_Factory.java:9)
   at com.example.okhttpexample.data.repository.DataRepository_Factory.get(DataRepository_Factory.java:36)
   at com.example.okhttpexample.data.repository.DataRepository_Factory.get(DataRepository_Factory.java:10)
   at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
   at com.example.okhttpexample.di.DaggerApplicationComponent.injectMainActivity(DaggerApplicationComponent.java:600)
   at com.example.okhttpexample.di.DaggerApplicationComponent.inject(DaggerApplicationComponent.java:526)
   at com.example.okhttpexample.MainActivity.onCreate(MainActivity.java:75)
   at android.app.Activity.performCreate(Activity.java:7955)
   at android.app.Activity.performCreate(Activity.java:7944)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3423)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
   at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
   at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147)
   at android.os.Handler.dispatchMessage(Handler.java:107)
   at android.os.Looper.loop(Looper.java:237)
   at android.app.ActivityThread.main(ActivityThread.java:7811)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
TikTak
  • 713
  • 1
  • 11
  • 23

2 Answers2

8

Update 1:

Ensure you are using okhttp with version 4.3.1 or above.

You need to add the following to the proguard file inorder to avoid crash on Android 10.

-keepclassmembers class * implements javax.net.ssl.SSLSocketFactory {
    private final javax.net.ssl.SSLSocketFactory delegate;
}

Please note that in my SocketFactory class, I had the following field:

private final SSLSocketFactory delegate;

So adjust the ProGuard rule accordingly. E.g, the access modifiers like private, final, etc. as well as the field name (delegate) should match exactly as written in the class file.


You need to add the following to the Application tag in your manifest file to make it work with latest android versions.

android:usesCleartextTraffic="true"

Create a trust manager that does not validate certificate chains

        final TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                }
        };

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();

Register the sslSocketFactory with OkHttpClient builder

OkHttpClient.Builder builder = new OkHttpClient.Builder();

builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

That's all.

Darish
  • 11,032
  • 5
  • 50
  • 70
0

Android 10 requires an upgraded version of Okhttp, upgrade the version will solve the Required method checkServerTrusted error.

implementation 'com.squareup.okhttp3:okhttp:4.8.0'