Java.security.cert.CertPathValidatorException: привязка доверия для пути сертификации не найдена. Android 2.3

На моем сервере (производственном сервере) у меня есть сертификат goDaddy ssl. У меня есть приложения для iOS и Android, подключающиеся к серверу, iOS без проблем, андроид с версиями 4. * все хорошо, но с устройствами с 2.3. * Я всегда получаю исключение SSLHandshakeException.

Я сделал именно это на странице разработчиков Android ( https://developer.android.com/training/articles/security-ssl.html ).

Я уже видел подобные потоки здесь в stackoverflow ( здесь ), но никто не помогает.

Затем я увидел, что этот поток говорит об использовании расширенного ключа, но при отладке я получаю следующую информацию:

[2]: OID: 2.5.29.37, Critical: false Extended Key Usage: [ "1.3.6.1.5.5.7.3.1", "1.3.6.1.5.5.7.3.2" ] 

Поэтому я считаю, что сертификат не «форсирует» расширенное использование ключа.

Также в этой теме есть некоторые другие возможные причины, такие как дата / время, которые являются полностью неправильными, которых все еще не существует.

Принимая это во внимание, я теперь не знаю, где проблема.

Какие-либо предложения?

EDIT: StackTrace:

 08-04 16:54:30.139: W/System.err(4832): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 08-04 16:54:30.149: W/System.err(4832): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:161) 08-04 16:54:30.149: W/System.err(4832): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:664) 08-04 16:54:30.149: W/System.err(4832): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method) 08-04 16:54:30.159: W/System.err(4832): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:474) 

Похоже, что эмитент вашего сертификата не находится в хранилище доверия 2.3.

Ознакомьтесь с корневым и промежуточным сертификатом своего сертификата GoDaddy и проверьте наличие сертификатов на вашем устройстве 2.3.

См. http://www.andreabaccega.com/blog/2010/09/23/android-root-certification-authorities-list/ для получения списка из 2.3 сертификатов.

Когда доступен только корневой ЦС, убедитесь, что ваш веб-сервер также обслуживает промежуточные сертификаты по запросу.

Я просмотрел множество мест в SO и в Интернете, чтобы решить эту проблему. Это код, который работал для меня (Android 21):

  ByteArrayInputStream derInputStream = new ByteArrayInputStream(app.certificateString.getBytes()); CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC"); X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream); String alias = "alias";//cert.getSubjectX500Principal().getName(); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null); trustStore.setCertificateEntry(alias, cert); KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); kmf.init(trustStore, null); KeyManager[] keyManagers = kmf.getKeyManagers(); TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); tmf.init(trustStore); TrustManager[] trustManagers = tmf.getTrustManagers(); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagers, trustManagers, null); URL url = new URL(someURL); conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(sslContext.getSocketFactory()); 

App.certificateString – это строка, содержащая сертификат, например:

  static public String certificateString= "-----BEGIN CERTIFICATE-----\n" + "MIIGQTCCBSmgAwIBAgIHBcg1dAivUzANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UE" + "BhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBE" + ... a bunch of characters... "5126sfeEJMRV4Fl2E5W1gDHoOd6V==\n" + "-----END CERTIFICATE-----"; 

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