java.security.cert.CertPathValidatorException: якорь доверия для пути сертификации не найден. на апи меньше 24

com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

Я получил эту ошибку в logcat на API с 19 по 24, и в моем приложении нет загрузки данных с сервера. Я искал эту ошибку и обнаружил, что решение

 @SuppressLint("TrulyRandom")
public static void handleSSLHandshake() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        }};

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception ignored) {
    }
}

и вызовите его в моем классе приложения onCreate, и это решило мою проблему, но в этом ответе, который, если найти это решение, есть подсказка Этот код не имеет значения и не должен использоваться! это запрещено Google.

так кто-нибудь знает, какое альтернативное решение разрешено Google для этой ошибки?


person Amin    schedule 05.05.2019    source источник


Ответы (2)


сначала вам нужно будет создать файл сертификата, и вот шаги

  • перейти по ссылке на ваш сайт в браузере Firefox

  • нажмите на зеленый замок справа от ссылки на сайт

  • нажмите на дополнительную информацию, затем просмотрите сертификат

  • появится новое окно с двумя касаниями общее и подробности выберите детали

  • нажмите на экспорт, чтобы экспортировать свой сертификат и сохранить этот файл в активах проекта Android.

во-вторых, в классе приложения вашего проекта определите переменную hurlStack и используйте следующий метод в приложении OnCreate Method

 private void handleCertificationOnOlderDevices() {
    try {

        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = new 
                            BufferedInputStream(getAssets().open("porter_cert.crt"));
        Certificate ca;
        try {
            ca = cf.generateCertificate(caInput);
            Log.d("certificate", ((X509Certificate) ca).getSubjectDN().toString());
        } finally {
            caInput.close();
        }

        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        TrustManager[] trustManagers = tmf.getTrustManagers();
        final X509TrustManager origTrustmanager =  
                                                (X509TrustManager) trustManagers[0];

        TrustManager[] wrappedTrustManagers = new TrustManager[]{
                new X509TrustManager() {
                   public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return origTrustmanager.getAcceptedIssuers();
                   }

                   public void checkClientTrusted(X509Certificate[] certs,  
                   String authType) 
                   {
                        try {
                            origTrustmanager.checkClientTrusted(certs, authType);
                        } catch (CertificateException e) {
                            e.printStackTrace();
                        }
                    }

                    public void checkServerTrusted(X509Certificate[] certs,
                    String authType) 
                    {
                        try {
                            origTrustmanager.checkServerTrusted(certs, authType);
                        } catch (CertificateException e) {
                            e.printStackTrace();
                        }
                    }
                }
        };

        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        SSLSocketFactory sslSocketFactory = context.getSocketFactory();
        hurlStack = new HurlStack(null, sslSocketFactory);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

и при запросе залпа Очередь используйте hurlStack

    public RequestQueue getRequestQueue() {
       if (requestQueue == null)
           requestQueue = Volley.newRequestQueue(getApplicationContext(), 
           hurlStack);
       return requestQueue;
    }

в-третьих, если вы используете Glide для изображений, вы получите вторую ошибку с сертификатом ssl, связанную с glide, и вам нужно будет решить ее таким образом.

1 - обновить в приложении сборку gilde и okhttp3 до этой версии

    implementation "com.squareup.okhttp3:okhttp:3.8.1"
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
    implementation ('com.github.bumptech.glide:okhttp3-integration:4.9.0'){
    exclude group: 'glide-parent'
    }

2 - добавить следующий класс в ваш проект

@GlideModule 
public class CustomGlideModule extends AppGlideModule {
   @Override
   public void registerComponents(Context context, Glide glide,  
   Registryregistry) {
      if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
          OkHttpClient client = 
                        SafeOkHttpClient.getSafeOkHttpClient(context);
          OkHttpUrlLoader.Factory factory = new 
                                       OkHttpUrlLoader.Factory(client);
          glide.getRegistry().replace(GlideUrl.class, InputStream.class, 
          factory);
      }
   }

 }

и теперь скольжение будет отлично работать с вами.

person Osama Abdelaziz    schedule 20.05.2019

Какая версия TLS на вашем сервере? Скорее всего это 1.2 или выше. Для устройств kitkat версия 1.2 по умолчанию отключена, и ее необходимо включить . Если на ваших устройствах есть сервисы Google Play, вы можете сделать это через это. В противном случае вам нужен пользовательский класс фабрики сокетов, который указывает 1.2 и, возможно, 1.3.

Если он ниже 1.2, почтовые устройства Kitkat не будут разрешать подключения, если вы не доверяете всем сертификатам с помощью взлома в вашем вопросе. Он не должен быть ниже.

person Daniel Wilson    schedule 06.05.2019