java.security.cert.CertPathValidatorException: доверенная привязка для пути сертификации не найдена.на API меньше 24 - PullRequest
3 голосов
/ 05 мая 2019
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 для этой ошибки?

Ответы [ 2 ]

1 голос
/ 20 мая 2019

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

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

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

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

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

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

секунда в вашем проекте: класс приложения определяет переменную hurlStack и использует следующий метод в методе OnCreate приложения

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

 }

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

1 голос
/ 06 мая 2019

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

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

...