Trust Anchor introuvable pour la connexion SSL Android

185

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

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

J'ai essayé de déterminer ce qui pouvait en être la cause, mais en train de dessiner des blancs 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()); 
Chrispix
la source

Réponses:

78

La solution de @Chrispix est dangereuse! Faire confiance à tous les certificats permet à quiconque de faire une attaque d'homme au milieu! Envoyez simplement N'IMPORTE QUEL certificat au client et il l'acceptera!

Ajoutez vos certificats à un gestionnaire de confiance personnalisé comme décrit dans cet article: Faire confiance à tous les certificats à l'aide de HttpClient sur HTTPS

Bien qu'il soit un peu plus complexe d'établir une connexion sécurisée avec un certificat personnalisé, cela vous apportera la sécurité de cryptage ssl souhaitée sans le danger d'une attaque de l'homme au milieu!

Matthias B
la source
1
C'est correct pour travailler avec un certificat auto-généré, mais pour l'un (comme les OP) qui a une chaîne valide vers les CA racine, c'est juste une solution de contournement pour un serveur mal configuré - voir ma réponse.
Stevie
4
@Stevie Accepter CHAQUE certificat n'est qu'une option pour un test de preuve de concept, où la connexion SSL n'est pas la partie que vous souhaitez tester. Sinon, vous n'êtes pas obligé d'utiliser SSL, si vous acceptez tous les certificats, car la connexion n'est pas sécurisée!
Matthias B
1
Ah, je suis désolé, je pense qu'il y a un malentendu - je suis tout à fait d'accord que personne ne devrait jamais accepter chaque certificat! :) Mon commentaire concernait votre 2ème paragraphe - la suggestion d'utiliser un gestionnaire de confiance personnalisé - dont IMHO devrait être une solution de contournement de dernier recours plutôt qu'une solution recommandée.
Stevie
2
Jut a heads up .. J'ai supprimé la «solution» que j'avais collée comme solution de contournement pour ne pas causer plus de problèmes, car les gens ne la voyaient pas comme un «travail temporaire».
Chrispix
7
@Chrispix, vous n'auriez pas dû supprimer le correctif partiel, c'est bon uniquement à des fins de test
Hugo Allexis Cardona
224

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

J'ai rencontré le même problème lors de la connexion à 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 - testez-le avec http://www.digicert.com/help/ ou similaire, et il vous indiquera même la solution:

"Le certificat n'est pas signé par une autorité de confiance (vérification par rapport au magasin racine de Mozilla). Si vous avez acheté le certificat auprès d'une autorité de confiance, il vous suffit probablement d'installer un ou plusieurs certificats intermédiaires . Contactez votre fournisseur de certificats pour obtenir de l'aide. plate-forme 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 seul é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 renvoyer les autorités signataires d'une chaîne à une chaîne approuvée 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 la configuration de votre serveur sont généralement fournies par l'autorité qui a émis votre certificat, par exemple: http://www.alphassl.com/support/install-root-certificate.html

Après avoir installé les certificats intermédiaires fournis par mon émetteur de certificat, je n'ai plus d'erreurs lors de la connexion à l'aide de HttpsUrlConnection.

Stevie
la source
3
Si l'OP a accès à la configuration SSL du serveur auquel il se connecte, cela peut être une solution. Mais s'il n'est pas celui qui héberge le service auquel il se connecte, il doit résoudre le problème de son côté, c'est-à-dire implémenter un gestionnaire de confiance personnalisé.
Matthias B
9
Votre solution fonctionne, pas de question, mais n'êtes-vous pas d'accord pour dire qu'il s'agit d'une solution de contournement plutôt que d'un correctif pour la cause première? Si je dois me connecter à un serveur à partir de 3 clients (Android, iOS, Windows Mobile), alors je dois appliquer la solution de contournement sur les 3, alors que je peux réparer le serveur une fois et qu'ils "fonctionneront tous simplement".
Stevie
2
Merci Stevie, j'ai eu mon serveur mal configuré pendant 3 mois, et c'est seulement maintenant que je l'ai détecté! Maintenant, mon application Android fonctionne à 100%
jpros
2
@Stevie Je fais de nombreux appels à différentes API qui partagent le même domaine, mais une seule d'entre elles échoue avec (javax.net.ssl.SSLHandshakeException) ... une idée de la raison pour laquelle une telle chose se produirait? et au fait, le certificat SSL n'est pas fiable. Donc, j'ai pensé que tous les appels devaient échouer avec la même exception.
un joueur équitable
1
@dvaey contacte celui qui possède le serveur et leur dit que leur configuration est cassée et que leur https ne fonctionne pas correctement - donnez-leur ce lien pour le prouver digicert.com/help ... J'imagine qu'ils seraient reconnaissants et rapides à résoudre. Sinon, vous devrez suivre l'une des étapes de contournement dans les autres réponses, mais vous devrez alors accepter aucune sécurité (ignorer les certificats) ou redéployer vos applications lorsque le certificat expire et que votre magasin de confiance personnalisé ne correspond plus au nouveau cert.
Stevie
17

Vous pouvez faire confiance à un certificat particulier au moment de l'exécution.
Téléchargez-le simplement à partir du serveur, insérez des actifs et chargez-le 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é OkHttpClientmais SSLContextpeut être utilisé avec n'importe quel client en Java.

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

Klimat
la source
qu'en est-il du .pfx?
Choletski
2
N'est-ce pas dangereux puisque tout utilisateur peut accéder au dossier des actifs d'une application une fois qu'il a l'apk?
Patrice Andala
1
@PatriceAndala, les autorités de certification racine sont accessibles au public, donc c'est ok
BekaBot
17

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

Lorsque 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)

le problème peut être l'un des suivants:

  1. L'autorité de certification qui a émis le certificat de serveur était inconnue
  2. Le certificat de serveur n'a pas été signé par une autorité de certification, mais était auto-signé
  3. Il manque une autorité de certification intermédiaire dans la configuration du serveur

La solution consiste à apprendre HttpsURLConnectionà faire confiance à un ensemble spécifique d'autorités de certification. Comment? Veuillez vérifier https://developer.android.com/training/articles/security-ssl.html#CommonProblems

Pour les autres utilisateurs AsyncHTTPClientde la com.loopj.android:android-async-httpbibliothèque, veuillez vérifier Setup AsyncHttpClient pour utiliser HTTPS .

user1506104
la source
5
Et si l'on utilise un client okhttp?
TheLearner
Pour okhttp, veuillez vérifier la réponse de @ mklimek.
user1506104
14

Si vous utilisez la mise à niveau, vous devez personnaliser votre OkHttpClient.

retrofit = new Retrofit.Builder()
                        .baseUrl(ApplicationData.FINAL_URL)
                        .client(getUnsafeOkHttpClient().build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();

Le code complet est comme ci-dessous.

    public class RestAdapter {

    private static Retrofit retrofit = null;
    private static ApiInterface apiInterface;

    public static OkHttpClient.Builder getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            return builder;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static ApiInterface getApiClient() {
        if (apiInterface == null) {

            try {
                retrofit = new Retrofit.Builder()
                        .baseUrl(ApplicationData.FINAL_URL)
                        .client(getUnsafeOkHttpClient().build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();

            } catch (Exception e) {

                e.printStackTrace();
            }


            apiInterface = retrofit.create(ApiInterface.class);
        }
        return apiInterface;
    }

}
Shihab Uddin
la source
1
J'essaye d'utiliser le code mais j'obtiens à nouveau l'erreur suivante. "Javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: ancre de confiance pour le chemin de certification introuvable." can u help in this
Vishwa Pratap
Ceci est radicalement peu sûr. Ne pas utiliser.
Marquis of Lorne
Merci! Réécriture de la méthode getUnsafeOkHttpClient()dans Kotlin: stackoverflow.com/a/60507560/2914140 .
CoolMind
11

En réponse à un très ancien message. Mais peut-être que cela aidera certains débutants et si aucune des réponses ci-dessus ne fonctionne.

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

Solution: la solution suivante suppose que les conditions suivantes sont remplies

  1. Essayer d'accéder à une API distante à partir de votre machine locale.
  2. Vous construisez pour l'application Android
  3. Votre serveur distant est soumis à un filtrage proxy (vous utilisez un proxy dans les paramètres de votre navigateur pour accéder au service API distant, généralement un serveur de développement ou de développement)
  4. Vous testez sur un appareil réel

Pas:

Vous avez besoin d'un fichier d'extension .keystore pour inscrire votre application. Si vous ne savez pas comment créer un fichier .keystore; puis suivez la section suivante Créer un fichier .keystore ou passez à la section suivante Signer un fichier Apk

Créer un fichier .keystore

Ouvrez Android Studio. Cliquez sur le menu du haut Créer> Générer un APK signé. Dans la fenêtre suivante cliquez sur le Créer un nouveau ... bouton. Dans la nouvelle fenêtre, veuillez saisir des données dans tous les champs. Rappelez-vous que les deux champs de mot de passe que je recommande devraient avoir le même mot de passe; n'utilisez pas de mot de passe différent; et rappelez-vous également le chemin de sauvegarde en haut de la plupart des champs Chemin du magasin de clés: . Après avoir entré tout le champ, cliquez sur le bouton OK.

Signer le fichier Apk

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

  1. Build> Clean Project, attendez qu'il ait fini de nettoyer
  2. Créer> Générer un APK signé
  3. Cliquez sur Choose existing... bouton
  4. Sélectionnez le fichier .keystore que nous venons de créer dans le fichier Create .keystore section
  5. Entrez le même mot de passe que vous avez créé lors de la création dans la section Créer un fichier .keystore . Utilisez le même mot de passe pour les champs Key store passwordet Key password. Saisissez également l'alias
  6. Cliquez sur le bouton Suivant
  7. Dans l'écran suivant; qui peuvent être différents en fonction de vos paramètres dans les build.gradlefichiers, vous devez sélectionner Build Typeset Flavors.
  8. Pour le Build Typeschoix releasedans la liste déroulante
  9. Car Flavorscependant cela dépendra de vos paramètres dans le build.gradlefichier. Choisissez stagingdans 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 nom applicationIdde votre package

    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. Cochez les deux Signature Versionscases du bas et cliquez sur le Finishbouton.

Presque là:

Tout le travail est fait, maintenant le mouvement de la vérité. Afin d'accéder au serveur Staging sauvegardé par proxy, vous devez effectuer des réglages dans vos vrais appareils Android de test.

Paramètre proxy dans l'appareil Android:

  1. Cliquez sur le paramètre à l'intérieur du téléphone Android, puis sur Wi-Fi
  2. Appuyez longuement sur le wifi connecté et sélectionnez Modify network
  3. Cliquez sur Advanced optionssi vous ne pouvez pas voir le Proxy Hostnamechamp
  4. Dans le, Proxy Hostnameentrez l'adresse IP ou le nom de l'hôte que vous souhaitez connecter. Un serveur intermédiaire typique sera nommé commestg.api.mygoodcompany.com
  5. Pour le port, entrez le numéro de port à quatre chiffres par exemple 9502
  6. Appuyez sur le Savebouton

Un dernier arrêt:

N'oubliez pas que nous avons généré le fichier apk signé dans la section Signer le fichier APK . Il est maintenant temps d'installer ce fichier APK.

  1. Ouvrez un terminal et changé dans le dossier du fichier apk signé
  2. Connectez votre appareil Android à votre machine
  3. Supprimez tout fichier apk précédemment installé de l'appareil Android
  4. Courir adb install name of the apk file
  5. Si pour une raison quelconque, la commande ci-dessus revient 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. Sinon, laissez-moi un commentaire.

Salam!

A
la source
4

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

Donc en général, si le certificat est là dans le keystore et son "VALID", cette erreur se produira.

MPN
la source
1
Si le certificat est expiré, il n'est pas valide selon un certain nombre de normes. Son OK pour utiliser une coutume TrustManageret utiliser un ensemble différent de critères. Mais dès le départ, c'est ce avec quoi vous devez travailler.
jww
4

J'ai eu le même problème lors de la connexion du client Android au serveur Kurento. Le serveur Kurento utilise des certificats jks, j'ai donc dû convertir pem en lui. Comme entrée pour la conversion, j'ai utilisé le fichier cert.pem et cela a conduit à de telles erreurs. Mais si l' utilisation fullchain.pem au lieu de cert.pem - tout est OK.

V.Poddubchak
la source
3

Utilisez https://www.ssllabs.com/ssltest/ pour tester un domaine.

La solution de Shihab Uddin à Kotlin.

import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.security.cert.CertificateException

companion object {

    private val gson: Gson
    private val retrofit: Retrofit

    init {

        val okHttpClient = getUnsafeOkHttpClient() // OkHttpClient().newBuilder()
            .build()

        gson = GsonBuilder().setLenient().create()

        retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    }

    private fun getUnsafeOkHttpClient(): OkHttpClient.Builder =
        try {
            // Create a trust manager that does not validate certificate chains
            val trustAllCerts: Array<TrustManager> = arrayOf(
                object : X509TrustManager {
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    @Throws(CertificateException::class)
                    override fun checkServerTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
                }
            )
            // Install the all-trusting trust manager
            val sslContext: SSLContext = SSLContext.getInstance("SSL")
            sslContext.init(null, trustAllCerts, SecureRandom())
            // Create an ssl socket factory with our all-trusting manager
            val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
            val builder = OkHttpClient.Builder()
            builder.sslSocketFactory(sslSocketFactory,
                trustAllCerts[0] as X509TrustManager)
            builder.hostnameVerifier { _, _ -> true }
            builder
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
}
CoolMind
la source
2

J'ai eu le même problème que j'ai trouvé, c'est que le fichier de certificat .crt que j'ai fourni manquait un certificat intermédiaire. J'ai donc demandé tous les fichiers .crt à l'administrateur de mon serveur, puis les ai concaténés dans l'ordre inverse.

Ex. 1. Root.crt 2. Inter.crt 3. myCrt.crt

dans Windows, j'ai exécuté la copie Inter.crt + Root.crt newCertificate.crt

(Ici, j'ai ignoré myCrt.crt)

Ensuite, j'ai fourni le fichier newCertificate.crt dans le code via le flux d'entrée. Travail effectué.

Sahan Maldeniya
la source
Nous avons également eu le même problème. Certificat intermédiaire manquant
Nidhin Chandran
1

L'erreur d'ancrage de confiance peut se produire pour de nombreuses raisons. Pour moi, c'était simplement que j'essayais d'accéder https://example.com/au lieu de https://www.example.com/.

Vous voudrez peut-être revérifier vos URL avant de commencer à créer votre propre Trust Manager (comme je l'ai fait).

Unkulunkulu
la source
0

Dans les téléphones Gingerbread, j'obtiens toujours cette erreur: Trust Anchor not found for Android SSL Connection même si je me fie à mon certificat.

Voici le code que j'utilise (en langage 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)
}

Fondamentalement, je configure pour faire confiance à mon certificat personnalisé. Si cela échoue, je désactive la sécurité. Ce n'est pas la meilleure option, mais le seul choix que je connaisse avec les téléphones anciens et bogués.

Cet exemple de code peut être facilement traduit en Java.

david.perez
la source
Solution pour Android 2.3.x au cas où quelqu'un en aurait besoin, stackoverflow.com/a/46465722/7125370
Débutant009
0

Dans mon cas, cela se produisait après la mise à jour vers Android 8.0. Le certificat auto-signé qu'Android a été configuré pour faire confiance utilisait l'algorithme de signature SHA1withRSA. Le passage à un nouveau certificat à l'aide de l'algorithme de signature SHA256withRSA a résolu le problème.

Zds
la source
0

Je sais que vous n'avez pas besoin de faire confiance à tous les certificats, mais dans mon cas, j'ai eu des problèmes avec certains environnements de débogage où nous avions des certificats auto-signés et j'avais besoin d'une solution sale.

Tout ce que j'avais à faire était de changer l'initialisation du sslContext

mySSLContext.init(null, trustAllCerts, null); 

où a trustAllCertsété créé comme ceci:

private final 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 {
    }
} };

J'espère que cela vous sera utile.

Adrian C.
la source
C'est ce que je voulais trouver! Merci
oxied
J'obtiens une erreur Hostname '192.168.0.16' was not verified. Je teste mon webapi via mon débogueur (IIS Express) localement. Une idée de comment résoudre ce problème? Merci :)
Sam
1
Ceci est radicalement incertain. Ne pas utiliser.
Marquis of Lorne
0

J'ai eu un problème similaire et j'ai complètement exclu la stratégie de faire confiance à toutes les sources.

Je partage ici ma solution appliquée à une application implémentée dans Kotlin

Je recommanderais d'abord d'utiliser le site Web suivant pour obtenir des informations sur le certificat et sa validité

S'il n'apparaît pas comme `` émetteurs acceptés '' dans le magasin de confiance par défaut d'Android , nous devons obtenir ce certificat et l'incorporer dans l'application pour créer un magasin de confiance personnalisé

La solution idéale dans mon cas était de créer un gestionnaire de confiance de haut niveau qui combine le magasin de confiance par défaut personnalisé et Android

Ici, il expose le code de haut niveau utilisé pour configurer le OkHttpClient qu'il a utilisé avec Retrofit.

override fun onBuildHttpClient(httpClientBuild: OkHttpClient.Builder) {

        val trustManagerWrapper = createX509TrustManagerWrapper(
            arrayOf(
                getCustomX509TrustManager(),
                getDefaultX509TrustManager()
            )
        )

        printX509TrustManagerAcceptedIssuers(trustManagerWrapper)

        val sslSocketFactory = createSocketFactory(trustManagerWrapper)
        httpClientBuild.sslSocketFactory(sslSocketFactory, trustManagerWrapper)

    }

De cette façon, je pourrais communiquer avec le serveur avec un certificat auto-signé et avec d'autres serveurs avec un certificat émis par une entité de certification de confiance

Ça y est, j'espère que ça peut aider quelqu'un.

Sergio Sánchez Sánchez
la source
0

Je sais que c'est un très vieil article, mais je suis tombé sur cet article en essayant de résoudre mes problèmes d'ancrage de confiance. J'ai posté comment je l'ai corrigé. Si vous avez pré-installé votre autorité de certification racine, vous devez ajouter une configuration au manifeste.

https://stackoverflow.com/a/60102517/114265

Envoyé GR
la source
uniquement pour API 24+
BekaBot
@BekaBot - c'est probablement vrai, mais selon la documentation 23 et ci-dessous, faites confiance aux certificats d'utilisateurs par défaut.Par défaut, les connexions sécurisées (à l'aide de protocoles tels que TLS et HTTPS) de toutes les applications font confiance aux autorités de certification système préinstallées et aux applications ciblant Android 6.0 (API niveau 23) et inférieur font également confiance au magasin CA ajouté par l'utilisateur par défaut
GR Envoy
-1
**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);
Dayanand Waghmare
la source
-2

J'ai également rencontré le même problème. Je supprime simplement hhtps vers http, comme

final public static String ROOT_URL = "https://example.com"; à final public static String ROOT_URL = "http://example.com";

Enfin, j'ai résolu ce problème.

Rasheduzzaman
la source
Il ne s'agit certainement que de supprimer la sécurité SSL de l'équation, ce qui est probablement une mauvaise idée pour un environnement de production.
Dragonthoughts
Ce n'est vraiment pas une solution, supprimant la sécurité SSL.
omega1 le