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());
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!
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.
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.
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:
- L'AC qui a émis le certificat de serveur était inconnue
- le certificat du serveur n'était pas signé par une AC, mais était auto-signé
- 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 .
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
- essayer d'accéder à une api distante depuis votre machine locale.
- vous construisez pour Android app
- 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)
- 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
- Build > Nettoyage de Projet, attendez qu'il soit terminer le nettoyage de la
- Build > Générer Signé APK
- , Cliquez sur
Choose existing...
bouton - sélectionnez le .keystore fichier que nous venons de créer dans le créer .fichier de magasin de clés de la section
- 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
etKey password
. Entrez aussi l'alias - cliquez sur le bouton Suivant
- dans l'écran suivant; qui peut être différent en fonction de vos paramètres dans les fichiers
build.gradle
, vous devez sélectionnerBuild Types
etFlavors
. - pour le
Build Types
choisissezrelease
liste déroulante -
pour
Flavors
cependant cela dépendra de vos réglages dansbuild.gradle
fichier. Choisissezstaging
dans ce champ. J'ai utilisé les paramètres suivants dans lebuild.gradle
, vous pouvez utiliser le même que le mien, mais assurez-vous de changer leapplicationId
à votre nom de paquetproductFlavors { 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" } }
-
cliquez sur les deux dernières cases à cocher
Signature Versions
et cliquez sur le boutonFinish
.
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:
- cliquez sur le paramètre à L'intérieur du téléphone Android et ensuite wi-fi
- appuyez longtemps sur le wifi connecté et sélectionnez
Modify network
- cliquez sur le
Advanced options
si vous ne pouvez pas voir le "champProxy Hostname
1519410920" - 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
- pour le port inscrire le numéro de port à quatre chiffres, par exemple
9502
- 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.
- ouvrir un terminal et changé pour le dossier signé apk
- Connectez votre appareil Android à votre machine
- supprimer tout fichier apk installé l'appareil Android
- Exécuter
adb install
name of the apk file
- si, pour une raison quelconque, la commande ci-dessus retourne avec
adb command not found
. Entrez le chemin complet commeC:\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!
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.
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.
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é.
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.
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.
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).
**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);