Es sollte beachtet werden, dass die Antworten auf diese Frage nicht mehr als das tun, was gefragt wird: Sie können den Fehler ignorieren, aber das zugrunde liegende Problem nicht beheben (ein bisschen wie das Entfernen der Batterien aus einem Rauchmelder, anstatt das Feuer zu löschen ). Zertifikate dienen dazu, die Sicherheit der SSL / TLS-Verbindung zu gewährleisten. Das Ignorieren dieser Fehler führt zu einer Sicherheitsanfälligkeit für MITM-Angriffe. Verwenden Sie Testzertifikate, anstatt den Fehler zu ignorieren.
"wie das Entfernen der Batterien aus einem Rauchmelder" Sie könnten anderen Entwicklern den Vorteil des Zweifels geben und davon ausgehen, dass sie wissen, was sie tun. Vielleicht liegt die Motivation für diese Frage in lokalen Tests, und das OP möchte einen schnellen Test durchführen, ohne die schrecklichen Mengen an Java-Boilerplate zu durchlaufen, die zum Einrichten selbst einer einfachen SSL-Umgebung erforderlich sind. Vielleicht könnte jemand die Frage einfach beantworten, ohne in einen Vortrag "Heiliger als du" zu gehen.
Mike
Das heißt, in unserem unternehmensinternen JIRA-Server gibt es ein "Windows-Sicherheitsrichtlinien-basiertes Zertifikat", das auf Windows-Computern gültig ist, die in der Domäne enthalten sind, und auf anderen Computern nicht gültig ist. Ich kann diese Richtlinie nicht steuern und möchte trotzdem die JIRA REST-API aufrufen.
odiszapc
1
@Bruno Die Unfähigkeit, Rauchmelder für einen Zeitraum von 30 bis 60 Minuten zu deaktivieren, während ich mich mit einem kleinen Küchenbrand befasse, zeigt einen wahnsinnigen Mangel an Einsicht in die Verwendungsmuster eines gesetzlichen Beamten an einem Punkt, an dem ich mich als kriminell fühle. Die Tatsache, dass es ein Konzept zum "Entfernen von Batterien aus einem Rauchmelder" gibt, beweist dies. Ich bin ungefähr genauso verärgert darüber, dass ich Zertifikate für einen einfachen Test benötigen muss, von dem ich weiß, dass er keine Auswirkungen auf die Sicherheit hat. Die Existenz dieser Frage beweist dies.
Bill K
Antworten:
84
Sie müssen einen SSLContext mit Ihrem eigenen TrustManager erstellen und unter Verwendung dieses Kontexts ein HTTPS-Schema erstellen. Hier ist der 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);
Angenommen, ich möchte kein gültiges SSL-Zertifikat für meine Site kaufen und es nur verwenden. Dieser Code kann helfen. Wie kommt es, dass ich keinen Teil sehe, in dem eine URL benötigt wird oder eine Ausnahmebehandlung erforderlich ist?
Viet
19
Hmm, es sagt mir, dass 'new SSLSocketFactory (ssslCont)' einen KeyStore erwartet, keinen SSLContext. Vermisse ich etwas
MSpeed
2
Ich erhalte die Fehlermeldung, dass ein X509TrustManager nicht in einen TrustManager umgewandelt werden kann.
MW.
2
Stellen Sie sicher, dass Sie die richtigen Pakete importieren, dh aus org.apache.http.
Direktor
2
Weiß jemand, wie man das alles zusammenwirft HttpClientBuilder?
Ali
112
Alle anderen Antworten waren entweder veraltet oder funktionierten für HttpClient 4.3 nicht.
Hier ist eine Möglichkeit, alle Hostnamen beim Erstellen eines http-Clients zuzulassen.
Vielen Dank für die Antwort. Ich möchte wissen, aus welchem Paket HttpsClients stammt, wie ich es in der Android-Kompilierung verwende ("org.apache.httpcomponents: httpclient: 4.3.4"), aber diese Klasse wird nicht angezeigt.
Juan Saravia
1
Das Paket lautet org.apache.http.impl.client.HttpClients.
Erversteeg
14
Dies funktioniert um eine Nichtübereinstimmung des Hostnamens (ich nehme an), aber es scheint nicht zu funktionieren, wenn das Zertifikat nicht von einer vertrauenswürdigen Behörde signiert ist.
Twm
1
@twm Aus diesem Grund heißt es, dass "alle Hostnamen zulässig sind". Vertrauensprobleme erfordern eine andere Konfiguration.
Eis
1
@eis, ich habe darauf hingewiesen, dass diese Antwort in bestimmten Fällen die ursprüngliche Frage anspricht, in anderen jedoch nicht.
Twm
43
Musste dies nur mit dem neueren HttpClient 4.5 machen und es scheint, als hätten sie seit 4.4 ein paar Dinge veraltet. Hier ist das Snippet, das für mich funktioniert und die neueste API verwendet:
Danke dir! Ändern Sie einfach TrustAllStrategy.INSTANCEmit TrustSelfSignedStrategy.INSTANCEin dieser Antwort.
Percy Vega
Das hat bei mir nicht funktioniert. javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX-Pfaderstellung fehlgeschlagen: sun.security. provider.certpath.SunCertPathBuilderException: Es konnte kein gültiger Zertifizierungspfad zum angeforderten Ziel gefunden werden
ggb667
26
Für die Aufzeichnung, getestet mit httpclient 4.3.6 und kompatibel mit Executor of Fluent API:
Ab HttpClient 4.4 müssen Sie dies tun - und müssen möglicherweise auch eine erstellen , die dies SSLConnectionSocketFactoryverwendet SSLContext, und dies in a definieren Registry<ConnectionSocketFactory>, wenn Sie eine erstellen möchten PoolingHttpClientConnectionManager. Die anderen Antworten sind beliebter, funktionieren aber bei HttpClient 4.4 nicht.
Thomas W
1
Funktioniert genau so mit httpclient-4.3.5.jar.
Harald
18
Für 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();
Dies wird aus unserer tatsächlichen Arbeitsimplementierung extrahiert.
Die anderen Antworten sind beliebt, aber für HttpClient 4.4 funktionieren sie nicht. Ich habe Stunden damit verbracht, Möglichkeiten auszuprobieren und auszuschöpfen, aber es scheint bei 4.4 extrem große Änderungen und Verschiebungen der API gegeben zu haben.
Die Methode sf.setHostnameVerifier ist ab 4.1 veraltet. Die Alternative besteht darin, einen der Konstruktoren zu verwenden. Zum Beispiel:SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Kaliatech
Dies war sehr nützlich, wenn ich mich mit Legacy-Code befassen musste.
DuncanSungWKim
9
Wir verwenden HTTPClient 4.3.5 und haben versucht, dass fast alle Lösungen im Stackoverflow existieren, aber nichts. Nachdem wir das Problem überlegt und herausgefunden haben, kommen wir zu dem folgenden Code, der perfekt funktioniert. Fügen Sie ihn einfach hinzu, bevor Sie eine HttpClient-Instanz erstellen.
Dies ist die einzige Lösung, die für mich funktioniert hat. Ich habe die oben genannten Lösungen für 4.3 und 4.4 ausprobiert, bevor ich auf 4.5 aktualisiert und dies versucht habe.
Dirkoneill
6
So habe ich es gemacht -
Erstellen Sie meine eigene MockSSLSocketFactory (Klasse unten angefügt)
Verwenden Sie diese Option, um DefaultHttpClient zu initialisieren. Proxy-Einstellungen müssen angegeben werden, wenn ein Proxy verwendet wird.
DefaultHTTPClient wird initialisiert -
SchemeRegistry schemeRegistry =newSchemeRegistry();
schemeRegistry.register(newScheme("http",80,PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(newScheme("https",443,newMockSSLSocketFactory()));ClientConnectionManager cm =newSingleClientConnManager(schemeRegistry);DefaultHttpClient httpclient =newDefaultHttpClient(cm);
Sie können das gleiche erreichen, indem Sie einfach tunsf.setHostnameVerifier(new AllowAllHostnameVerifier());
Dan Dyer
7
Der sf.setHostnameVerifier ist ab 4.1 veraltet. Die Alternative besteht darin, einen der Konstruktoren zu verwenden. Zum Beispiel: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);}
Ich erhalte Folgendes: Auslöser: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Keine alternativen Betreffnamen vorhanden?
Wie erlaube ich Verbindungen zu SSL-Sites ohne Zertifikate in der HttpClient-API oder in der RestClient-API?
4
Getestet mit HttpClient 4.5.5 mit Fluent API
finalSSLContext sslContext =newSSLContextBuilder().loadTrustMaterial(null,(x509CertChain, authType)->true).build();CloseableHttpClient httpClient =HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext).build();String result =Executor.newInstance(httpClient).execute(Request.Get("https://localhost:8080/someapi").connectTimeout(1000).socketTimeout(1000)).returnContent().asString();
Vielen Dank für die aktualisierte Antwort. Ich habe dem neuen Mann das Kopfgeld für "Willkommen" verliehen, aber ich wollte nur aktualisierte Antworten für alle!
1
@ Feelingunwelcome, sicher. Ich habe ihn auch positiv bewertet :-)
Tarun Lalwani
2
eine voll funktionsfähige Version für Apache HttpClient 4.1.3 (basierend auf dem obigen Code von oleg, aber es wurde immer noch ein allow_all_hostname_verifier auf meinem System benötigt):
Wenn dieses Problem bei der Verwendung von AmazonS3Client aufgetreten ist, in das Apache HttpClient 4.1 eingebettet ist, müssen Sie lediglich eine solche Systemeigenschaft definieren, damit die SSL-Zertifizierungsprüfung gelockert wird:
Wenn Sie Apache httpClient 4.5.x verwenden, versuchen Sie Folgendes :
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();}
Antworten:
Sie müssen einen SSLContext mit Ihrem eigenen TrustManager erstellen und unter Verwendung dieses Kontexts ein HTTPS-Schema erstellen. Hier ist der Code,
quelle
HttpClientBuilder
?Alle anderen Antworten waren entweder veraltet oder funktionierten für HttpClient 4.3 nicht.
Hier ist eine Möglichkeit, alle Hostnamen beim Erstellen eines http-Clients zuzulassen.
Wenn Sie Version 4.4 oder höher verwenden, sieht der aktualisierte Aufruf folgendermaßen aus:
quelle
Musste dies nur mit dem neueren HttpClient 4.5 machen und es scheint, als hätten sie seit 4.4 ein paar Dinge veraltet. Hier ist das Snippet, das für mich funktioniert und die neueste API verwendet:
quelle
Nur zur Veranschaulichung: Es gibt eine viel einfachere Möglichkeit, dies mit HttpClient 4.1 zu erreichen
quelle
new SSLSocketFactory((chain, authType) -> true);
Apache HttpClient 4.5.5
Es wurde keine veraltete API verwendet.
Einfacher überprüfbarer Testfall:
quelle
TrustAllStrategy.INSTANCE
mitTrustSelfSignedStrategy.INSTANCE
in dieser Antwort.Für die Aufzeichnung, getestet mit httpclient 4.3.6 und kompatibel mit Executor of Fluent API:
quelle
SSLConnectionSocketFactory
verwendetSSLContext
, und dies in a definierenRegistry<ConnectionSocketFactory>
, wenn Sie eine erstellen möchtenPoolingHttpClientConnectionManager
. Die anderen Antworten sind beliebter, funktionieren aber bei HttpClient 4.4 nicht.Für Apache HttpClient 4.4:
Dies wird aus unserer tatsächlichen Arbeitsimplementierung extrahiert.
Die anderen Antworten sind beliebt, aber für HttpClient 4.4 funktionieren sie nicht. Ich habe Stunden damit verbracht, Möglichkeiten auszuprobieren und auszuschöpfen, aber es scheint bei 4.4 extrem große Änderungen und Verschiebungen der API gegeben zu haben.
Siehe auch eine etwas ausführlichere Erklärung unter: http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/
Hoffentlich hilft das!
quelle
Wenn Sie nur ungültige Hostnamenfehler beseitigen möchten, können Sie einfach Folgendes tun:
quelle
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Wir verwenden HTTPClient 4.3.5 und haben versucht, dass fast alle Lösungen im Stackoverflow existieren, aber nichts. Nachdem wir das Problem überlegt und herausgefunden haben, kommen wir zu dem folgenden Code, der perfekt funktioniert. Fügen Sie ihn einfach hinzu, bevor Sie eine HttpClient-Instanz erstellen.
quelle
Mit fließendem 4.5.2 musste ich die folgenden Änderungen vornehmen, damit es funktioniert.
quelle
So habe ich es gemacht -
DefaultHTTPClient wird initialisiert -
Mock SSL Factory -
Wenn Sie sich hinter einem Proxy befinden, müssen Sie dies tun -
quelle
In Erweiterung der Antwort von ZZ Coder ist es hilfreich, den Hostnamenverifier zu überschreiben.
quelle
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
quelle
Um alle Zertifikate in HttpClient 4.4.x zu akzeptieren, können Sie beim Erstellen des httpClient den folgenden Liner verwenden:
quelle
Getestet mit HttpClient 4.5.5 mit Fluent API
quelle
Der folgende Code funktioniert mit
4.5.5
Ausgabe von Code ist
Ausgabe im Browser ist
Der verwendete Pom ist unten
quelle
eine voll funktionsfähige Version für Apache HttpClient 4.1.3 (basierend auf dem obigen Code von oleg, aber es wurde immer noch ein allow_all_hostname_verifier auf meinem System benötigt):
Beachten Sie, dass ich alle Ausnahmen erneut auslöse, da ich wirklich nicht viel tun kann, wenn dies in einem realen System fehlschlägt!
quelle
Wenn Sie die fließende API verwenden , müssen Sie sie über Folgendes einrichten
Executor
:... wo
sslContext
wird der SSLContext erstellt, wie in der Antwort des ZZ- Codierers gezeigt .Danach können Sie Ihre http-Anfragen wie folgt ausführen:
Hinweis: getestet mit HttpClient 4.2
quelle
Getestet mit 4.3.3
}}
quelle
Getestet am 4.5.4:
quelle
Wenn dieses Problem bei der Verwendung von AmazonS3Client aufgetreten ist, in das Apache HttpClient 4.1 eingebettet ist, müssen Sie lediglich eine solche Systemeigenschaft definieren, damit die SSL-Zertifizierungsprüfung gelockert wird:
-Dcom.amazonaws.sdk.disableCertChecking = true
Unfug schaffte es
quelle
fwiw, ein Beispiel für die Verwendung der "RestEasy" -Implementierung von JAX-RS 2.x zum Erstellen eines speziellen "Trust All" -Clients ...
verwandte Maven-Abhängigkeiten
quelle
Wenn Sie Apache httpClient 4.5.x verwenden, versuchen Sie Folgendes :
quelle