L'ancre de confiance n'a pas été trouvée pour la connexion SSL Android

j'essaie de me connecter à une boîte IIS6 qui exécute un certificat godaddy 256bit SSL, et j'obtiens l'erreur:

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

a essayé de déterminer ce qui pourrait causer ça, mais en train de tirer à blanc.

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()); 
117
demandé sur David Grinberg 2011-07-26 08:22:51

12 réponses

la solution de @Chrispix est dangereuse! faire confiance à tous les certificats permet à n'importe qui de faire un homme dans l'attaque du milieu! il suffit d'envoyer N'importe quel certificat au client et il l'acceptera!

ajoutez votre(vos) certificat (s) à un gestionnaire de confiance personnalisé comme décrit dans ce post: faites confiance à tous les certificats en utilisant HttpClient sur HTTPS

bien qu'il soit 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!

58
répondu Matthias B 2018-08-27 16:32:11

contrairement à la réponse acceptée vous ne pas besoin d'un gestionnaire de confiance personnalisé, vous devez corriger la configuration de votre serveur!

j'ai frappé le même problème en me connectant à un serveur Apache avec un certificat dynadot/alphassl mal installé. Je me connecte en utilisant HttpsUrlConnection (Java / Android), qui lançait -

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 - le tester avec http://www.digicert.com/help / ou similaire, et il vous dira même la solution:

" le certificat n'est pas signé par une autorité de confiance (en vérifiant s'il s'agit du magasin root de Mozilla). Si vous avez acheté le certificat d'une autorité de confiance, vous avez probablement juste besoin d'installer un ou plusieurs certificats intermédiaires . Communiquez avec votre fournisseur de certificat pour obtenir de l'aide à cet égard. plate-forme de serveur."

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

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

vous verrez probablement:

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 ne contiendra qu'un élément (votre certificat):

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

... mais il faudrait faire référence aux pouvoirs de signature dans un chaîne de retour à un qui est de confiance 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

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

après avoir installé les certificats intermédiaires fournis par l'émetteur de mon certificat, Je n'ai plus aucune erreur lors de la connexion via HttpsUrlConnection.

159
répondu Stevie 2013-04-30 14:36:24

vous pouvez faire confiance à un certificat particulier à l'exécution.

Il suffit de le télécharger à partir du serveur, mettre en actifs et charger comme ceci en utilisant ssl-utils-android :

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

Dans l'exemple ci-dessus, j'ai utilisé OkHttpClient mais SSLContext peut être utilisé avec n'importe quel client en Java.

Si vous avez des questions n'hésitez pas à demander. Je suis l'auteur de cette petite bibliothèque.

14
répondu klimat 2016-10-05 21:01:57

mise à jour basée sur la dernière documentation Android (mars 2017):

quand vous obtenez ce type d'erreur:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
        at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
        at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
        at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
        at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

la question pourrait être l'une des suivantes:

  1. L'AC qui a émis le certificat de serveur était inconnue
  2. le certificat du serveur n'était pas signé par une AC, mais était auto-signé
  3. la configuration du serveur est manquante un intermédiaire CA

la solution est d'enseigner HttpsURLConnection à faire confiance à un ensemble spécifique de CA. Comment? Veuillez cocher https://developer.android.com/training/articles/security-ssl.html#CommonProblems

autres qui utilisent AsyncHTTPClient de com.loopj.android:android-async-http bibliothèque, s'il vous plaît vérifier Setup AsyncHttpClient pour utiliser HTTPS .

10
répondu user1506104 2017-05-23 12:03:09

Répondant à de très vieux post. Mais peut-être que cela aidera certains débutants et si non de la ci-dessus fonctionne.

explication: je sais que personne ne veut d'explication de merde; plutôt la solution. Mais dans un liner, vous essayez d'accéder à un service depuis votre machine locale vers une machine distante qui ne fait pas confiance à votre machine. Vous demandez besoin de gagner la confiance du serveur distant.

Solution: La solution suivante suppose que vous avez les conditions suivantes remplies

  1. essayer d'accéder à une api distante depuis votre machine locale.
  2. vous construisez pour Android app
  3. votre serveur distant est sous proxy filtration (vous utilisez proxy dans les paramètres de votre navigateur pour accéder au service d'api à distance, généralement un serveur de mise en scène ou de développement)
  4. Vous sont à l'essai sur un périphérique réel

Suit:

vous avez besoin d'un .fichier de stockage des clés d'extension de fichier pour l'inscription de votre application. Si vous ne savez pas comment les créer .keystore fichier; puis suivre avec la section suivante créer .fichier de magasin de clés ou sinon passer à la section suivante Signe Fichier Apk

créer .fichier de magasin de clés

Open Android Studio. Cliquez sur le menu du haut construire > générer APK signé. Dans la fenêtre suivante cliquez sur le créer nouveau... Bouton . Dans la nouvelle fenêtre, entrez des données dans tous les domaines. Souvenez-vous que le champ "deux mots de passe" que je recommande devrait avoir le même mot de passe; n'utilisez pas de mot de passe différent; et souvenez-vous également du chemin de sauvegarde dans le champ chemin de magasin de clés: . Après avoir saisi tout le champ, cliquez sur le bouton OK.

Signe Fichier Apk

Maintenant, vous devez construire une application signée avec le .fichier keystore que vous venez de créer. Suivez ces étapes

  1. Build > Nettoyage de Projet, attendez qu'il soit terminer le nettoyage de la
  2. Build > Générer Signé APK
  3. , Cliquez sur Choose existing... bouton
  4. sélectionnez le .keystore fichier que nous venons de créer dans le créer .fichier de magasin de clés de la section
  5. Entrez le même mot de passe que vous avez créé lors de la création de créer .fichier de magasin de clés section. Utilisez le même mot de passe pour les champs Key store password et Key password . Entrez aussi l'alias
  6. cliquez sur le bouton Suivant
  7. dans l'écran suivant; qui peut être différent en fonction de vos paramètres dans les fichiers build.gradle , vous devez sélectionner Build Types et Flavors .
  8. pour le Build Types choisissez release liste déroulante
  9. pour Flavors cependant cela dépendra de vos réglages dans build.gradle fichier. Choisissez staging dans ce champ. J'ai utilisé les paramètres suivants dans le build.gradle , vous pouvez utiliser le même que le mien, mais assurez-vous de changer le applicationId à votre nom de paquet

    productFlavors { staging { applicationId "com.yourapplication.package" manifestPlaceholders = [icon: "@drawable/ic_launcher"] buildConfigField "boolean", "CATALYST_DEBUG", "true" buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true" } production { buildConfigField "boolean", "CATALYST_DEBUG", "false" buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false" } }

  10. cliquez sur les deux dernières cases à cocher Signature Versions et cliquez sur le bouton Finish .

Presque Là:

tout le travail est fait, maintenant le mouvement de la vérité. Afin d'accéder au serveur de mise en scène sauvegardé par proxy, vous avez besoin de faire quelques réglages dans vos appareils Android de test réels.

paramètre Proxy sur Android Device:

  1. cliquez sur le paramètre à L'intérieur du téléphone Android et ensuite wi-fi
  2. appuyez longtemps sur le wifi connecté et sélectionnez Modify network
  3. cliquez sur le Advanced options si vous ne pouvez pas voir le "champ Proxy Hostname 1519410920"
  4. dans le Proxy Hostname entrez L'adresse IP de l'hôte ou le nom que vous souhaitez connecter. Un serveur de staging typique sera nommé stg.api.mygoodcompany.com
  5. pour le port inscrire le numéro de port à quatre chiffres, par exemple 9502
  6. appuyez sur le bouton Save

Un Dernier Arrêt:

rappelez-vous que nous avons généré le fichier apk signé dans la section Sign APK File . Il est maintenant temps d'installer ce fichier APK.

  1. ouvrir un terminal et changé pour le dossier signé apk
  2. Connectez votre appareil Android à votre machine
  3. supprimer tout fichier apk installé l'appareil Android
  4. Exécuter adb install name of the apk file
  5. si, pour une raison quelconque, la commande ci-dessus retourne avec adb command not found . Entrez le chemin complet comme C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe install name of the apk file

j'espère que le problème pourra être résolu. Si ce n'est pas le cas, veuillez me laisser un commentaire.

Salam!

6
répondu HA S 2018-03-16 05:43:12

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

Donc, en général, si le certificat dans le keystore et ses "VALIDE", cette erreur s'éteint.

4
répondu MPN 2013-06-28 11:59:57

j'ai eu le même problème en me connectant de client Android à serveur Kurento. Kurento server utilise des certificats jks, donc j'ai dû convertir pem. Comme entrée pour la conversion j'ai utilisé cert.pem et cela conduit à de telles erreurs. Mais si vous utilisez fullchain.pem au lieu de cert.pem - tout va bien.

2
répondu V.Poddubchak 2017-10-11 11:24:52

j'ai eu le même problème que le certificat .le fichier crt i a fourni un certificat intermédiaire manquant. J'ai donc demandé à tous .les fichiers crt de l'administrateur de mon serveur, puis concatiné dans l'ordre inverse.

ex. 1. Racine.CRT 2. Inter.CRT 3. myCrt.crt

dans windows, j'ai exécuté copie de l'Inter.crt + Root.crt newCertificate.crt

(ici j'ai ignoré myCrt.crt)

alors j'ai fourni newCertificate.crt file dans le code via inputstream. Le travail effectué.

1
répondu sahan maldeniya 2015-08-12 10:35:39

dans les téléphones en Gingerbread, je reçois toujours cette erreur: Trust Anchor not found for Android SSL Connection , même si je me configure pour compter sur mon certificat.

voici le code que j'utilise (en langue Scala):

object Security {
    private def createCtxSsl(ctx: Context) = {
        val cer = {
            val is = ctx.getAssets.open("mycertificate.crt")
            try
                CertificateFactory.getInstance("X.509").generateCertificate(is)
            finally
                is.close()
        }
        val key = KeyStore.getInstance(KeyStore.getDefaultType)
        key.load(null, null)
        key.setCertificateEntry("ca", cer)

        val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    tmf.init(key)

        val c = SSLContext.getInstance("TLS")
        c.init(null, tmf.getTrustManagers, null)
        c
    }

    def prepare(url: HttpURLConnection)(implicit ctx: Context) {
        url match {
            case https: HttpsURLConnection ⇒
                val cSsl = ctxSsl match {
                    case None ⇒
                        val res = createCtxSsl(ctx)
                        ctxSsl = Some(res)
                        res
                    case Some(c) ⇒ c
                }
                https.setSSLSocketFactory(cSsl.getSocketFactory)
            case _ ⇒
        }
    }

    def noSecurity(url: HttpURLConnection) {
        url match {
            case https: HttpsURLConnection ⇒
                https.setHostnameVerifier(new HostnameVerifier {
                    override def verify(hostname: String, session: SSLSession) = true
                })
            case _ ⇒
        }
    }
}

et voici le code de connexion:

def connect(securize: HttpURLConnection ⇒ Unit) {
    val conn = url.openConnection().asInstanceOf[HttpURLConnection]
    securize(conn)
    conn.connect();
    ....
}

try {
    connect(Security.prepare)
} catch {
    case ex: SSLHandshakeException /*if ex.getMessage != null && ex.getMessage.contains("Trust anchor for certification path not found")*/ ⇒
        connect(Security.noSecurity)
}

en gros, je me prépare à faire confiance sur mon certificat personnalisé. Si ça échoue, je désactiverai la sécurité. Ce n'est pas la meilleure option, mais le seul choix que je connais avec les téléphones vieux et buggy.

cet exemple de code, peut être facilement traduit en Java.

0
répondu david.perez 2015-03-24 16:01:02

dans mon cas, cela se passait après la mise à jour vers Android 8.0. Le certificat auto-signé Android a été mis à confiance était en utilisant l'algorithme de signature SHA1withRSA. La commutation à un nouveau cert, En utilisant l'algorithme de signature SHA256withRSA a corrigé le problème.

0
répondu Zds 2018-03-16 17:01:31

L'ancre de Confiance erreur peut se produire pour beaucoup de raisons. Pour moi, c'était simplement que j'essayais d'accès https://example.com/ au lieu de https://www.example.com/ .

donc vous pourriez vouloir revérifier vos URLs avant de commencer à construire votre propre gestionnaire de confiance (comme je l'ai fait).

0
répondu Unkulunkulu 2018-07-31 09:19:51
**Set proper alias name**
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");
            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
            String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
-1
répondu Dayanand Waghmare 2016-03-04 14:36:52