Как отключить проверку SSL? - PullRequest
1 голос
/ 07 февраля 2020

Я пытался отключить проверку SSL в своем приложении, но приложение вылетает в Android 10 на некоторых устройствах. Я использовал в своем приложении Retrofit и Okhttp. Вот как я пытался отключить проверку SSL в моем приложении. Я не нашел никакого решения от inte rnet.

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

В Android 10 я ловлю это исключение

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) 

Это исключение из сбоев. Так же бывает только в 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)

1 Ответ

2 голосов
/ 07 февраля 2020

Обновление 1:

Убедитесь, что вы используете okhttp с версией 4.3.1 или выше.

Вам необходимо добавить следующее в порядок файлов proguard, чтобы избежать cra sh on Android 10.

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

Обратите внимание, что в моем классе SocketFactory у меня было следующее поле:

private final SSLSocketFactory delegate;

Поэтому настройте правило ProGuard соответствующим образом , Например, модификаторы доступа, такие как private, final, et c. а также имя поля (делегат) должно совпадать в точности так, как написано в файле класса.


Вам нужно добавить следующее в тег Application в файле манифеста, чтобы он работал с последними android версии.

android:usesCleartextTraffic="true"

Создание диспетчера доверия, который не проверяет цепочки сертификатов

        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[]{};
                    }
                }
        };

Установка доверенного диспетчера

 final SSLContext sslContext = SSLContext.getInstance("SSL");
 sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

Создание фабрики сокетов ssl с нашим полностью доверяющим менеджером

final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

Регистрация sslSocketFactory с помощью компоновщика OkHttpClient

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

Вот и все.

...