262 votes

Ancre de confiance introuvable pour la connexion SSL Android

J'essaie de me connecter à une boîte IIS6 exécutant un certificat SSL godaddy 256 bits et j'obtiens le message d'erreur suivant:

java.security.cert.CertPathValidatorException: L'ancre de confiance pour le chemin de certification est introuvable.

J'essayais de déterminer ce qui pouvait être la cause de cela, mais je fais des trous en ce moment.

Voici comment je me connecte:

 HttpsURLConnection conn;              
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream()); 
 

293voto

Stevie Points 1515

Contrairement à la accepté de répondre que vous n'avez pas besoin d'un de confiance personnalisée manager, vous devez modifier la configuration de votre serveur!

J'ai frappé le même problème lors de la connexion à un serveur Apache avec un mal installé dynadot/alphassl certificat. Je me connecte à l'aide de HttpsUrlConnection (Java/Android), qui jetait -

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

Le problème réel est une mauvaise configuration du serveur de test avec http://www.digicert.com/help/ ou similaires, et il va même jusqu'à vous dire la solution:

"Le certificat n'est pas signé par une autorité de confiance (de la vérification de Mozilla magasin racine). Si vous avez acheté le certificat auprès d'une autorité de confiance, vous avez probablement juste besoin d'installer un ou plusieurs certificats Intermédiaires. Contactez votre fournisseur de certificats pour l'assistance de le faire pour votre plate-forme de serveur."

Vous pouvez également vérifier le certificat avec openssl:

openssl s_client -debug -connect www.thedomaintocheck.com:443

Vous aurez probablement voir:

Verify return code: 21 (unable to verify the first certificate)

et, plus tôt dans la sortie:

depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`

La chaîne de certificats contiennent seulement 1 élément (votre certificat):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
  i:/O=AlphaSSL/CN=AlphaSSL CA - G2

... mais devrait faire référence à la signature des autorités dans une chaîne de retour à l'un, qui est approuvé par Android (Verisign, GlobalSign, etc):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
   i:/O=AlphaSSL/CN=AlphaSSL CA - G2
 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA

Des Instructions (et les certificats intermédiaires) pour la configuration de votre serveur sont généralement fournis par l'autorité qui a délivré le certificat, par exemple: http://www.alphassl.com/support/install-root-certificate.html

Après l'installation de l'intermédiaire des certificats fournis par mon émetteur du certificat, j'ai maintenant pas d'erreurs lors de la connexion à l'aide de HttpsUrlConnection.

93voto

elton Points 1706

La solution de @Chrispix est dangereux! Faire confiance à tous les certificats permet à quiconque de faire un man in the middle attack!!! Suffit d'envoyer un certificat du client et la volonté de l'accepter!!!

Ajouter vous certificat de confiance personnalisée gestionnaire comme décrit dans ce post: faire Confiance à tous les certificats à l'aide de HttpClient sur HTTPS

Aussi, il est un peu plus complexe d'établir une connexion sécurisée avec un certificat personnalisé, il vous apportera la sécurité par cryptage ssl, sans le danger de l'homme dans le milieu attaque!

14voto

Chrispix Points 4867

On dirait qu'il fonctionne avec le code suivant:

 // Code block for determining HTTP or https
    HttpURLConnection conn = null;
    URL url = new URL(mURL);
    if (url.getProtocol().toLowerCase().equals("https")) {
        trustAllHosts();
        HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
        https.setHostnameVerifier(DO_NOT_VERIFY);
        conn = https;
    } else {
        conn = (HttpURLConnection) url.openConnection();
    }
 

Voici les autres méthodes.

     // always verify the host - dont check for certificate
    final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
          public boolean verify(String hostname, SSLSession session) {
              return true;
          }
   };


    /**
     * Trust every server - dont check for any certificate
     */
    private static void trustAllHosts() {
              // Create a trust manager that does not validate certificate chains
              TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
                      public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                              return new java.security.cert.X509Certificate[] {};
                      }

                      public void checkClientTrusted(X509Certificate[] chain,
                                      String authType) throws CertificateException {
                      }

                      public void checkServerTrusted(X509Certificate[] chain,
                                      String authType) throws CertificateException {
                      }
              } };

              // Install the all-trusting trust manager
              try {
                      SSLContext sc = SSLContext.getInstance("TLS");
                      sc.init(null, trustAllCerts, new java.security.SecureRandom());
                      HttpsURLConnection
                                      .setDefaultSSLSocketFactory(sc.getSocketFactory());
              } catch (Exception e) {
                      e.printStackTrace();
              }
      }
 

4voto

MPN Points 1

Le message d'erreur que je recevais était similaire, mais la raison en était que le certificat auto-signé avait expiré. Lorsque le client openssl a été tenté, il m'a donné la raison qui avait été oubliée lorsque je vérifiais la boîte de dialogue de certificat de Firefox.

Donc, en général, si le certificat est présent dans le magasin de clés et que sa valeur est "VALID", cette erreur disparaîtra.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X