Il est à noter que les réponses à cette question ne font pas plus que ce qui est demandé: elles permettent d'ignorer l'erreur mais ne résolvent pas le problème sous-jacent (un peu comme retirer les piles d'un détecteur de fumée au lieu d'éteindre le feu ). Les certificats ont pour but d'assurer la sécurité de la connexion SSL / TLS, ignorer ces erreurs introduit une vulnérabilité à l'attaque MITM. Utilisez des certificats de test au lieu d'ignorer l'erreur.
"comme retirer les piles d'un détecteur de fumée" Vous pourriez donner à d'autres développeurs le bénéfice du doute et supposer qu'ils savent ce qu'ils font. Peut-être que la motivation de cette question est des tests locaux et l'OP souhaite exécuter un test rapide sans passer par les horribles quantités de passe-partout Java nécessaires pour mettre en place même un environnement SSL simple. Peut-être que quelqu'un pourrait simplement répondre à la question sans entrer dans une conférence «plus saint que toi».
Mike
Ie dans notre serveur interne JIRA de société a un certain "cert basé sur la politique de sécurité Windows" qui est valide sur les machines Windows incluses dans le domaine et non valide sur les autres. Je ne peux pas contrôler cette politique et je souhaite toujours appeler l'API JIRA REST.
odiszapc
1
@Bruno L'incapacité de désactiver les détecteurs de fumée pendant une période de 30 à 60 minutes tout en faisant face à un petit feu de cuisine montre un manque insensé de perspicacité dans les modes d'utilisation par un fonctionnaire juridique à un moment donné qui, je pense, frôle le criminel. Le fait qu'il existe un concept de «retrait des piles d'un détecteur de fumée» le prouve. Je ressens à peu près le même niveau de colère à l'idée de devoir obtenir des certificats pour un test simple dont je sais qu'il n'a pas de ramifications de sécurité. L'existence de cette question le prouve.
Bill K
Réponses:
84
Vous devez créer un SSLContext avec votre propre TrustManager et créer un schéma HTTPS en utilisant ce contexte. Voici le code,
SSLContext sslContext =SSLContext.getInstance("SSL");// set up a TrustManager that trusts everything
sslContext.init(null,newTrustManager[]{new X509TrustManager(){public X509Certificate[] getAcceptedIssuers(){System.out.println("getAcceptedIssuers =============");returnnull;}publicvoid checkClientTrusted(X509Certificate[] certs,String authType){System.out.println("checkClientTrusted =============");}publicvoid checkServerTrusted(X509Certificate[] certs,String authType){System.out.println("checkServerTrusted =============");}}},newSecureRandom());SSLSocketFactory sf =newSSLSocketFactory(sslContext);Scheme httpsScheme =newScheme("https",443, sf);SchemeRegistry schemeRegistry =newSchemeRegistry();
schemeRegistry.register(httpsScheme);// apache HttpClient version >4.2 should use BasicClientConnectionManagerClientConnectionManager cm =newSingleClientConnManager(schemeRegistry);HttpClient httpClient =newDefaultHttpClient(cm);
Dire que je ne veux pas acheter de certificat SSL valide pour mon site et que je veux simplement l'utiliser, ce morceau de code peut-il aider? Comment se fait-il que je ne vois aucune partie où une URL est nécessaire ou une gestion des exceptions est nécessaire?
Viet
19
Hmm, ça me dit que 'new SSLSocketFactory (ssslCont)' attend un KeyStore, pas un SSLContext. Est-ce que je manque quelque chose?
MSpeed le
2
J'obtiens l'erreur qu'un X509TrustManager ne peut pas être converti en TrustManager.
MW.
2
Assurez-vous d'importer les bons packages, c'est-à-dire depuis org.apache.http.
directeur du
2
Quelqu'un sait comment mettre tout cela ensemble en utilisant HttpClientBuilder?
Ali
112
Toutes les autres réponses étaient obsolètes ou ne fonctionnaient pas pour HttpClient 4.3.
Voici un moyen d'autoriser tous les noms d'hôte lors de la création d'un client http.
Merci pour la réponse, j'aimerais savoir de quel package provient HttpsClients comme j'utilise dans la compilation Android ("org.apache.httpcomponents: httpclient: 4.3.4") mais cette classe n'apparaît pas.
Juan Saravia
1
Son package est org.apache.http.impl.client.HttpClients.
erversteeg
14
Cela fonctionne autour d'une incompatibilité de nom d'hôte (je suppose), mais cela ne semble pas fonctionner lorsque le certificat n'est pas signé par une autorité de confiance.
twm
1
@twm c'est pourquoi il dit qu'il "autorise tous les noms d'hôte", les problèmes de confiance nécessitent une configuration différente.
eis
1
@eis, je faisais remarquer que cette réponse répond à la question d'origine dans certains cas mais pas dans d'autres.
twm
43
Je devais juste le faire avec le plus récent HttpClient 4.5 et il semble qu'ils aient abandonné certaines choses depuis la version 4.4, alors voici l'extrait qui fonctionne pour moi et utilise l'API la plus récente:
Je vous remercie! Changez simplement TrustAllStrategy.INSTANCEavec TrustSelfSignedStrategy.INSTANCEcette réponse.
Percy Vega
Cela n'a pas fonctionné pour moi. javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: la création du chemin PKIX a échoué: sun.security. provider.certpath.SunCertPathBuilderException: impossible de trouver un chemin de certification valide vers la cible demandée
ggb667
26
Pour mémoire, testé avec httpclient 4.3.6 et compatible avec Executor of fluent api:
Pour HttpClient 4.4 à partir de la version 4.4, vous devez le faire - et vous devrez peut-être également créer un en SSLConnectionSocketFactoryutilisant cela SSLContext, et le définir dans un Registry<ConnectionSocketFactory>, si vous allez créer un fichier PoolingHttpClientConnectionManager. Les autres réponses sont plus populaires, mais ne fonctionnent pas avec HttpClient 4.4.
Thomas W
1
Fonctionne exactement comme ça avec httpclient-4.3.5.jar.
Harald
18
Pour Apache HttpClient 4.4:
HttpClientBuilder b =HttpClientBuilder.create();SSLContext sslContext =newSSLContextBuilder().loadTrustMaterial(null,newTrustStrategy(){publicboolean isTrusted(X509Certificate[] arg0,String arg1)throwsCertificateException{returntrue;}}).build();
b.setSslcontext( sslContext);// or SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weakenHostnameVerifier hostnameVerifier =SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;SSLConnectionSocketFactory sslSocketFactory =newSSLConnectionSocketFactory(sslContext, hostnameVerifier);Registry<ConnectionSocketFactory> socketFactoryRegistry =RegistryBuilder.<ConnectionSocketFactory>create().register("http",PlainConnectionSocketFactory.getSocketFactory()).register("https", sslSocketFactory).build();// allows multi-threaded usePoolingHttpClientConnectionManager connMgr =newPoolingHttpClientConnectionManager( socketFactoryRegistry);
b.setConnectionManager( connMgr);HttpClient client = b.build();
Ceci est extrait de notre implémentation de travail réelle.
Les autres réponses sont populaires, mais pour HttpClient 4.4 elles ne fonctionnent pas. J'ai passé des heures à essayer et à épuiser les possibilités, mais il semble y avoir eu un changement et une relocalisation extrêmement importants de l'API à 4.4.
La méthode sf.setHostnameVerifier est obsolète depuis la version 4.1. L'alternative consiste à utiliser l'un des constructeurs. Par exemple:SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
kaliatech
C'était très utile lorsque je devais gérer du code hérité.
DuncanSungWKim
9
Nous utilisons HTTPClient 4.3.5 et nous avons essayé presque toutes les solutions existent sur le stackoverflow mais rien, après avoir réfléchi et compris le problème, nous arrivons au code suivant qui fonctionne parfaitement, il suffit de l'ajouter avant de créer l'instance HttpClient.
une méthode à appeler lors des demandes de publication ...
Vous pouvez réaliser la même chose en faisant simplementsf.setHostnameVerifier(new AllowAllHostnameVerifier());
Dan Dyer
7
Le sf.setHostnameVerifier est obsolète depuis la version 4.1. L'alternative consiste à utiliser l'un des constructeurs. Par exemple:SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
kaliatech
4
DefaultHttpClient httpclient =newDefaultHttpClient();SSLContext sslContext;try{
sslContext =SSLContext.getInstance("SSL");// set up a TrustManager that trusts everythingtry{
sslContext.init(null,newTrustManager[]{new X509TrustManager(){public X509Certificate[] getAcceptedIssuers(){
log.debug("getAcceptedIssuers =============");returnnull;}publicvoid checkClientTrusted(
X509Certificate[] certs,String authType){
log.debug("checkClientTrusted =============");}publicvoid checkServerTrusted(
X509Certificate[] certs,String authType){
log.debug("checkServerTrusted =============");}}},newSecureRandom());}catch(KeyManagementException e){}SSLSocketFactory ssf =newSSLSocketFactory(sslContext,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);ClientConnectionManager ccm =this.httpclient.getConnectionManager();SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(newScheme("https",443, ssf));}catch(Exception e){
log.error(e.getMessage(),e);}
merci pour la réponse mise à jour, j'ai attribué la prime au nouveau gars pour être "accueillant" mais je voulais juste des réponses mises à jour pour tout le monde!
1
@feelingunwelcome, bien sûr. Je l'ai également voté pour :-)
Tarun Lalwani
2
une version de travail complète pour Apache HttpClient 4.1.3 (basé sur le code d'oleg ci-dessus, mais il fallait toujours un allow_all_hostname_verifier sur mon système):
Si vous rencontrez ce problème lors de l'utilisation d'AmazonS3Client, qui intègre Apache HttpClient 4.1, il vous suffit de définir une propriété système comme celle-ci afin que le vérificateur de certificat SSL soit assoupli:
Si vous utilisez Apache httpClient 4.5.x, essayez ceci:
publicstaticvoid main(String... args){try(CloseableHttpClient httpclient = createAcceptSelfSignedCertificateClient()){HttpGet httpget =newHttpGet("https://example.com");System.out.println("Executing request "+ httpget.getRequestLine());
httpclient.execute(httpget);System.out.println("----------------------------------------");}catch(NoSuchAlgorithmException|KeyStoreException|KeyManagementException|IOException e){thrownewRuntimeException(e);}}privatestaticCloseableHttpClient createAcceptSelfSignedCertificateClient()throwsKeyManagementException,NoSuchAlgorithmException,KeyStoreException{// use the TrustSelfSignedStrategy to allow Self Signed CertificatesSSLContext sslContext =SSLContextBuilder.create().loadTrustMaterial(newTrustSelfSignedStrategy()).build();// we can optionally disable hostname verification. // if you don't want to further weaken the security, you don't have to include this.HostnameVerifier allowAllHosts =newNoopHostnameVerifier();// create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy// and allow all hosts verifier.SSLConnectionSocketFactory connectionFactory =newSSLConnectionSocketFactory(sslContext, allowAllHosts);// finally create the HttpClient using HttpClient factory methods and assign the ssl socket factoryreturnHttpClients.custom().setSSLSocketFactory(connectionFactory).build();}
Réponses:
Vous devez créer un SSLContext avec votre propre TrustManager et créer un schéma HTTPS en utilisant ce contexte. Voici le code,
la source
HttpClientBuilder
?Toutes les autres réponses étaient obsolètes ou ne fonctionnaient pas pour HttpClient 4.3.
Voici un moyen d'autoriser tous les noms d'hôte lors de la création d'un client http.
Ou si vous utilisez la version 4.4 ou ultérieure, l'appel mis à jour ressemble à ceci:
la source
Je devais juste le faire avec le plus récent HttpClient 4.5 et il semble qu'ils aient abandonné certaines choses depuis la version 4.4, alors voici l'extrait qui fonctionne pour moi et utilise l'API la plus récente:
la source
Pour mémoire, il existe un moyen beaucoup plus simple d'accomplir la même chose avec HttpClient 4.1
la source
new SSLSocketFactory((chain, authType) -> true);
Apache HttpClient 4.5.5
Aucune API obsolète n'a été utilisée.
Cas de test simple vérifiable:
la source
TrustAllStrategy.INSTANCE
avecTrustSelfSignedStrategy.INSTANCE
cette réponse.Pour mémoire, testé avec httpclient 4.3.6 et compatible avec Executor of fluent api:
la source
SSLConnectionSocketFactory
utilisant celaSSLContext
, et le définir dans unRegistry<ConnectionSocketFactory>
, si vous allez créer un fichierPoolingHttpClientConnectionManager
. Les autres réponses sont plus populaires, mais ne fonctionnent pas avec HttpClient 4.4.Pour Apache HttpClient 4.4:
Ceci est extrait de notre implémentation de travail réelle.
Les autres réponses sont populaires, mais pour HttpClient 4.4 elles ne fonctionnent pas. J'ai passé des heures à essayer et à épuiser les possibilités, mais il semble y avoir eu un changement et une relocalisation extrêmement importants de l'API à 4.4.
Voir également une explication un peu plus complète sur: http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/
J'espère que cela pourra aider!
la source
Si tout ce que vous voulez faire est de vous débarrasser des erreurs de nom d'hôte invalides, vous pouvez simplement faire:
la source
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Nous utilisons HTTPClient 4.3.5 et nous avons essayé presque toutes les solutions existent sur le stackoverflow mais rien, après avoir réfléchi et compris le problème, nous arrivons au code suivant qui fonctionne parfaitement, il suffit de l'ajouter avant de créer l'instance HttpClient.
la source
Avec la version 4.5.2 fluide, j'ai dû effectuer la modification suivante pour que cela fonctionne.
la source
Voilà comment je l'ai fait -
Initialisation de DefaultHTTPClient -
Usine SSL simulée -
Si derrière un proxy, vous devez le faire -
la source
Dans le prolongement de la réponse de ZZ Coder, il sera bien de remplacer le hostnameverifier.
la source
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
la source
Pour accepter tous les certificats dans HttpClient 4.4.x, vous pouvez utiliser la ligne suivante lors de la création du httpClient:
la source
Testé avec HttpClient 4.5.5 avec l'API Fluent
la source
Le code ci-dessous fonctionne avec
4.5.5
La sortie du code est
La sortie sur le navigateur est
Le pom utilisé est ci-dessous
la source
une version de travail complète pour Apache HttpClient 4.1.3 (basé sur le code d'oleg ci-dessus, mais il fallait toujours un allow_all_hostname_verifier sur mon système):
Notez que je relance toutes les exceptions car vraiment, je ne peux pas faire grand-chose si l'une de ces choses échoue dans un système réel!
la source
Si vous utilisez l' API fluent , vous devez la configurer via
Executor
:... où
sslContext
le SSLContext est-il créé comme indiqué dans la réponse du ZZ Coder .Après cela, vous pouvez faire vos requêtes http comme:
Remarque: testé avec HttpClient 4.2
la source
Testé avec 4.3.3
}
la source
Testé sur 4.5.4:
la source
Si vous rencontrez ce problème lors de l'utilisation d'AmazonS3Client, qui intègre Apache HttpClient 4.1, il vous suffit de définir une propriété système comme celle-ci afin que le vérificateur de certificat SSL soit assoupli:
-Dcom.amazonaws.sdk.disableCertChecking = true
Mal géré
la source
fwiw, un exemple utilisant l'implémentation "RestEasy" de JAX-RS 2.x pour construire un client spécial "trust all" ...
dépendances Maven associées
la source
Si vous utilisez Apache httpClient 4.5.x, essayez ceci:
la source