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)
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.