Récemment posté une question concernant les HttpClient
over Https ( trouvée ici ). J'ai fait des progrès, mais j'ai rencontré de nouveaux problèmes. Comme pour mon dernier problème, je n'arrive pas à trouver d'exemple n'importe où qui fonctionne pour moi. Fondamentalement, je veux que mon client accepte n'importe quel certificat (parce que je ne pointe que vers un serveur) mais je reçois toujours unjavax.net.ssl.SSLException: Not trusted server certificate exception.
Voici donc ce que j'ai:
public void connect() throws A_WHOLE_BUNCH_OF_EXCEPTIONS {
HttpPost post = new HttpPost(new URI(PROD_URL));
post.setEntity(new StringEntity(BODY));
KeyStore trusted = KeyStore.getInstance("BKS");
trusted.load(null, "".toCharArray());
SSLSocketFactory sslf = new SSLSocketFactory(trusted);
sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme ("https", sslf, 443));
SingleClientConnManager cm = new SingleClientConnManager(post.getParams(),
schemeRegistry);
HttpClient client = new DefaultHttpClient(cm, post.getParams());
HttpResponse result = client.execute(post);
}
Et voici l'erreur que je reçois:
W/System.err( 901): javax.net.ssl.SSLException: Not trusted server certificate
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:360)
W/System.err( 901): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:321)
W/System.err( 901): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:129)
W/System.err( 901): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
W/System.err( 901): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
W/System.err( 901): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:129)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.access$0(MainActivity.java:77)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity$2.run(MainActivity.java:49)
W/System.err( 901): Caused by: java.security.cert.CertificateException: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:157)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:355)
W/System.err( 901): ... 12 more
W/System.err( 901): Caused by: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty
W/System.err( 901): at java.security.cert.PKIXParameters.checkTrustAnchors(PKIXParameters.java:645)
W/System.err( 901): at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:89)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.<init>(TrustManagerImpl.java:89)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl.engineGetTrustManagers(TrustManagerFactoryImpl.java:134)
W/System.err( 901): at javax.net.ssl.TrustManagerFactory.getTrustManagers(TrustManagerFactory.java:226)W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.createTrustManagers(SSLSocketFactory.java:263)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:190)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:216)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:107)
W/System.err( 901): ... 2 more
java
ssl
https
certificate
apache-httpclient-4.x
Harrisonlee
la source
la source
Réponses:
Remarque: N'implémentez pas cela dans le code de production que vous allez utiliser sur un réseau auquel vous ne faites pas entièrement confiance. Surtout tout ce qui se passe sur Internet public.
Votre question est exactement ce que je veux savoir. Après avoir fait quelques recherches, la conclusion est la suivante.
De la manière HttpClient, vous devez créer une classe personnalisée à partir de org.apache.http.conn.ssl.SSLSocketFactory, et non celle org.apache.http.conn.ssl.SSLSocketFactory elle-même. Certains indices peuvent être trouvés dans cet article La gestion SSL personnalisée a cessé de fonctionner sur Android 2.2 FroYo .
Un exemple est comme ...
et utilisez cette classe lors de la création d'une instance de HttpClient.
BTW, le lien ci-dessous est pour quelqu'un qui recherche une solution HttpURLConnection. Connexion Https Android
J'ai testé les deux types de solutions ci-dessus sur froyo, et ils fonctionnent tous comme un charme dans mes cas. Enfin, l'utilisation de HttpURLConnection peut être confrontée aux problèmes de redirection, mais cela dépasse le sujet.
Remarque: Avant de décider de faire confiance à tous les certificats, vous devez probablement bien connaître le site et ne pas le nuire à l'utilisateur final.
En effet, le risque que vous prenez doit être soigneusement pris en compte, y compris l'effet du site simulé du pirate mentionné dans les commentaires suivants que j'ai profondément apprécié. Dans certaines situations, même s'il peut être difficile de s'occuper de tous les certificats, vous feriez mieux de connaître les inconvénients implicites de leur faire confiance.
la source
getAcceptedIssuers()
n'est pas autorisé à retourner null.Vous disposez essentiellement de quatre solutions potentielles pour corriger une exception "Non approuvé" sur Android en utilisant httpclient:
Cette réponse utilise la solution # 4, qui me semble la plus robuste.
La solution consiste à utiliser un SSLSocketFactory qui peut accepter plusieurs KeyStores, vous permettant de fournir votre propre KeyStore avec vos propres certificats. Cela vous permet de charger des certificats de niveau supérieur supplémentaires tels que Thawte qui pourraient être manquants sur certains appareils Android. Il vous permet également de charger vos propres certificats auto-signés. Il utilisera d'abord les certificats de périphérique par défaut intégrés et ne recourra à vos certificats supplémentaires que si nécessaire.
Tout d'abord, vous voudrez déterminer quel certificat vous manque dans votre KeyStore. Exécutez la commande suivante:
Et vous verrez une sortie comme celle-ci:
Comme vous pouvez le voir, notre certificat racine provient de Thawte. Accédez au site Web de votre fournisseur et recherchez le certificat correspondant. Pour nous, c'était ici , et vous pouvez voir que celui dont nous avions besoin était celui de Copyright 2006.
Si vous utilisez un certificat auto-signé, vous n'avez pas eu besoin de faire l'étape précédente car vous avez déjà votre certificat de signature.
Créez ensuite un fichier de clés contenant le certificat de signature manquant. Crazybob a des détails sur la façon de le faire sur Android , mais l'idée est de faire ce qui suit:
Si vous ne l'avez pas déjà, téléchargez la bibliothèque du fournisseur de château gonflable à partir de: http://www.bouncycastle.org/latest_releases.html . Cela ira sur votre chemin de classe ci-dessous.
Exécutez une commande pour extraire le certificat du serveur et créer un fichier pem. Dans ce cas, mycert.pem.
Exécutez ensuite les commandes suivantes pour créer le fichier de clés.
Vous remarquerez que le script ci-dessus place le résultat
res/raw/mystore.bks
. Vous avez maintenant un fichier que vous allez charger dans votre application Android qui fournit le ou les certificats manquants.Pour ce faire, enregistrez votre SSLSocketFactory pour le schéma SSL:
Pour créer votre SSLSocketFactory:
Et enfin, le code AdditionalKeyStoresSSLSocketFactory, qui accepte votre nouveau KeyStore et vérifie si le KeyStore intégré ne parvient pas à valider un certificat SSL:
la source
http://stackoverflow.com/questions/7822381/need-help-understanding-certificate-chains
Ajoutez ce code avant le
HttpsURLConnection
et ce sera fait. J? ai compris.J'espère que ceci vous aide.
la source
C'est une mauvaise idée. Faire confiance à un certificat n'est que (très) légèrement meilleur que de ne pas utiliser de SSL du tout. Lorsque vous dites «Je veux que mon client accepte n'importe quel certificat (parce que je ne pointe que vers un serveur)», vous supposez que cela signifie que pointer vers «un serveur» est sûr, ce qui n'est pas sur un réseau public.
Vous êtes complètement ouvert à une attaque d'homme au milieu en faisant confiance à n'importe quel certificat. Tout le monde peut proxy votre connexion en établissant une connexion SSL distincte avec vous et avec le serveur final. Le MITM a alors accès à l'ensemble de votre demande et réponse. À moins que vous n'ayez pas vraiment besoin de SSL en premier lieu (votre message n'a rien de sensible et ne fait pas d'authentification), vous ne devez pas faire confiance à tous les certificats à l'aveuglette.
Vous devriez envisager d'ajouter le certificat public à un jks à l'aide de keytool et de l'utiliser pour créer votre fabrique de socket, comme ceci:
Cela a une mise en garde à surveiller. Le certificat expirera finalement et le code cessera de fonctionner à ce moment-là. Vous pouvez facilement déterminer quand cela se produira en consultant le certificat.
la source
null
dansSSLContext.init). You should also use the default algorithms (KMF/TMF.getDefaultAlgorithm() ), instead of hard-coding
SunX509` (d'autant plus que la valeur par défaut pour TMF est en faitPKIX
sur la JVM Sun / Oracle).myjks.jks
vient-il?Vous pouvez désactiver la vérification SSL HttpURLConnection à des fins de test de cette façon depuis l'API 8:
la source
org.apache.http.conn.ssl.AllowAllHostnameVerifier
est obsolète.AllowAllHostnameVerifier
est remplacé parNoopHostnameVerifier
"L'API de HttpComponents a été modifiée. Cela fonctionne avec le code ci-dessous.
la source
Le code ci-dessus dans https://stackoverflow.com/a/6378872/1553004 est correct, sauf qu'il DOIT également appeler le vérificateur de nom d'hôte:
Je me suis inscrit à stackoverflow expressément pour ajouter ce correctif. Tenez compte de mon avertissement!
la source
J'ajoute une réponse pour ceux qui utilisent httpclient-4.5, et fonctionne probablement aussi pour 4.4.
la source
Faire confiance à tous les certificats n'était pas une véritable alternative pour moi, j'ai donc fait ce qui suit pour que HttpsURLConnection approuve un nouveau certificat (voir aussi http://nelenkov.blogspot.jp/2011/12/using-custom-certificate-trust-store- on.html ).
Obtenez le certificat; Je l'ai fait en exportant le certificat dans Firefox (cliquez sur la petite icône de verrouillage, obtenez les détails du certificat, cliquez sur exporter), puis j'ai utilisé portecle pour exporter un fichier de clés certifiées (BKS).
Chargez le Truststore depuis /res/raw/geotrust_cert.bks avec le code suivant:
la source
IOExceptionjavax.net.ssl.SSLPeerUnverifiedException: No peer certificate
. Cela lors de l'exécution de l'appel d'exécution réel sur le HttpClient après la configuration ci-dessus.Voici une version très simple utilisant le code httpclient 4.1.2. Cela peut ensuite être modifié pour n'importe quel algorithme de confiance que vous jugez bon.
la source
Je suis regardé la réponse de "emmby" (répondu le 16 juin 11 à 21:29), élément # 4: "Créer un SSLSocketFactory personnalisé qui utilise le certificat KeyStore intégré, mais retombe sur un autre KeyStore pour tout ce qui échoue pour vérifier avec la valeur par défaut. "
Il s'agit d'une implémentation simplifiée. Chargez le fichier de clés système et fusionnez avec le fichier de clés de l'application.
Un mode simple pour convertir de JKS en BKS:
* Remarque: dans Android 4.0 (ICS), le Trust Store a changé, plus d'informations: http://nelenkov.blogspot.com.es/2011/12/ics-trust-store-implementation.html
la source
Pour ceux qui souhaitent autoriser tous les certificats à fonctionner (à des fins de test) sur OAuth, procédez comme suit:
1) Téléchargez le code source de l'API Android OAuth ici: https://github.com/kaeppler/signpost
2) Trouvez le fichier "CommonsHttpOAuthProvider" classe
3) Modifiez-le comme ci-dessous:
Le "MySSLSocketFactory" ci-dessus est basé sur la réponse acceptée. Pour le rendre encore plus facile, voici la classe complète:
}
J'espère que cela aide quelqu'un.
la source
HttpClient
et HTTPS; pas OAuth pour Android à partir d'un projet GitHub.Je l'ai utilisé et cela fonctionne pour moi sur tous les OS.
la source
Il suffit d'ajouter des
-Dtrust_all_cert=true
arguments à la machine virtuelle. Cet argument indique à java d'ignorer les vérifications de certificats.la source
Tout organisme qui éprouve encore des difficultés avec les certificats SSL StartCom sur Android 2.1, visitez https://www.startssl.com/certs/ et téléchargez le ca.pem, maintenant dans la réponse fournie par @emmby replace
avec
Devrait fonctionner hors de la boîte. J'avais du mal pendant plus d'une journée même après une réponse parfaite de @emmby .. J'espère que cela aide quelqu'un ...
la source
utiliser cette classe
}
la source
entrez la description de l'image ici
Un sspi a échoué dans xamarin android.
J'ai trouvé cette solution; mettre ce code avant de cliquer sur un lien HTTPS
la source
travailler avec tous les https
la source
Il y a beaucoup de réponses ci-dessus mais je n'ai pas réussi à faire fonctionner correctement l'une d'entre elles (avec mon temps limité), donc pour toute autre personne dans la même situation, vous pouvez essayer le code ci-dessous qui fonctionnait parfaitement pour mes tests de java:
et appeler comme:
Référence: http://tech.chitgoks.com/2011/04/24/how-to-avoid-javax-net-ssl-sslpeerunverifiedexception-peer-not-authenticated-problem-using-apache-httpclient/
la source
Utilisez simplement ceci -
la source
La réponse de Daniel était bonne sauf que je devais changer ce code ...
à ce code ...
pour le faire fonctionner.
la source