Należy zauważyć, że odpowiedzi na to pytanie nie robią więcej niż to, co zostało zadane: pozwalają zignorować błąd, ale nie rozwiązują podstawowego problemu (trochę jak wyjęcie baterii z czujnika dymu zamiast ugaszenia ognia ). Certyfikaty mają na celu zapewnienie bezpieczeństwa połączenia SSL / TLS, ignorowanie tych błędów wprowadza podatność na atak MITM. Użyj certyfikatów testowych zamiast ignorować błąd.
„jak wyjmowanie baterii z czujnika dymu” Możesz dać innym programistom korzyści z wątpliwości i założyć, że wiedzą, co robią. Być może motywacją do tego pytania jest lokalne testowanie, a OP chce przeprowadzić szybki test bez przechodzenia przez okropną ilość gotowych elementów Javy potrzebnych do skonfigurowania nawet prostego środowiska SSL. Może ktoś mógłby po prostu odpowiedzieć na pytanie bez wchodzenia w wykład „bardziej święty niż ty”.
Mike
To znaczy, w naszej firmie, wewnętrzny serwer JIRA posiada „certyfikat oparty na polityce bezpieczeństwa systemu Windows”, który jest ważny na komputerach z systemem Windows w domenie, a nie na innych. Nie mogę kontrolować tej zasady i nadal chcę wywoływać interfejs API JIRA REST.
odiszapc
1
@Bruno Niemożność wyłączenia czujek dymu na okres 30-60 minut podczas zajmowania się małym kominkiem w kuchni wskazuje na szalony brak wglądu we wzorce użytkowania przez jakiegoś urzędnika prawnego w pewnym momencie, w którym czuję się na granicy przestępstwa. Dowodzi tego fakt, że istnieje koncepcja „wyjmowania baterii z czujnika dymu”. Czuję podobny poziom złości z powodu konieczności uzyskania certyfikatów potrzebnych do wykonania prostego testu, o którym wiem, że nie ma wpływu na bezpieczeństwo. Dowodzi tego istnienie tego pytania.
Bill K
Odpowiedzi:
84
Musisz utworzyć SSLContext z własnym TrustManager i utworzyć schemat HTTPS przy użyciu tego kontekstu. Oto kod,
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);
Powiedz, że nie chcę kupować ważnego certyfikatu SSL dla mojej witryny i chcę go po prostu użyć. Ten fragment kodu może pomóc? Dlaczego nie widzę żadnej części, w której potrzebny jest adres URL lub wymagana jest obsługa wyjątków?
Viet,
19
Hmm, mówi mi, że „nowy SSLSocketFactory (ssslCont)” oczekuje KeyStore, a nie SSLContext. Czy coś mi brakuje?
MSpeed
2
Pojawia się błąd, że X509TrustManager nie może być rzutowany na TrustManager.
MW.
2
Upewnij się, że importujesz poprawne pakiety, np. Z org.apache.http.
naczelnik
2
Czy ktoś wie, jak to wszystko połączyć, używając HttpClientBuilder?
Ali
112
Wszystkie pozostałe odpowiedzi były przestarzałe lub nie działały w przypadku HttpClient 4.3.
Oto sposób na zezwolenie na wszystkie nazwy hostów podczas budowania klienta http.
Dzięki za odpowiedź, chciałbym wiedzieć, z którego pakietu pochodzi HttpsClients, ponieważ używam kompilacji systemu Android („org.apache.httpcomponents: httpclient: 4.3.4”), ale ta klasa nie pojawia się.
Juan Saravia
1
Jego pakiet to org.apache.http.impl.client.HttpClients.
erversteeg
14
Działa to w przypadku niezgodności nazwy hosta (zakładam), ale wydaje się, że nie działa, gdy certyfikat nie jest podpisany przez zaufany urząd.
twm
1
@twm dlatego mówi, że „zezwala na wszystkie nazwy hostów”, problemy z zaufaniem wymagają innej konfiguracji.
eis
1
@eis, zwracałem uwagę, że ta odpowiedź w niektórych przypadkach dotyczy pierwotnego pytania, ale nie dotyczy innych.
twm
43
Po prostu musiałem to zrobić z nowszym HttpClient 4.5 i wygląda na to, że wycofali kilka rzeczy od 4.4, więc oto fragment kodu, który działa dla mnie i używa najnowszego interfejsu API:
Dziękuję Ci! Wystarczy zmienić TrustAllStrategy.INSTANCEsię TrustSelfSignedStrategy.INSTANCEw tej odpowiedzi.
Percy Vega,
To nie zadziałało dla mnie. javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: Tworzenie ścieżki PKIX nie powiodło się: sun.security. provider.certpath.SunCertPathBuilderException: nie można znaleźć prawidłowej ścieżki certyfikacji do żądanego celu
ggb667
26
Dla przypomnienia, przetestowany z httpclient 4.3.6 i kompatybilny z Executorem płynnego api:
W przypadku HttpClient 4.4 w górę musisz to zrobić - i może być również konieczne utworzenie SSLConnectionSocketFactoryużywającego go SSLContexti zdefiniowanie tego w a Registry<ConnectionSocketFactory>, jeśli masz zamiar utworzyć plik PoolingHttpClientConnectionManager. Pozostałe odpowiedzi są bardziej popularne, ale nie działają w HttpClient 4.4.
Thomas W
1
Działa dokładnie tak samo z httpclient-4.3.5.jar.
Harald
18
W przypadku 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();
Jest to wyodrębnione z naszej rzeczywistej implementacji roboczej.
Inne odpowiedzi są popularne, ale w przypadku HttpClient 4.4 nie działają. Spędziłem godziny próbując i wyczerpując możliwości, ale wydaje się, że nastąpiła bardzo duża zmiana API i przeniesienie w 4.4.
Metoda sf.setHostnameVerifier jest przestarzała od 4.1. Alternatywą jest użycie jednego z konstruktorów. Na przykład:SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
kaliatech
Było to bardzo przydatne, gdy miałem do czynienia ze starszym kodem.
DuncanSungWKim,
9
Używamy HTTPClient 4.3.5 i wypróbowaliśmy prawie wszystkie rozwiązania, które istnieją w przepływie stosu, ale nic. Po przemyśleniu i rozwiązaniu problemu dochodzimy do następującego kodu, który działa idealnie, po prostu dodaj go przed utworzeniem wystąpienia HttpClient.
jakaś metoda dzwonienia podczas wysyłania żądań pocztowych ...
Możesz osiągnąć to samo, po prostu robiącsf.setHostnameVerifier(new AllowAllHostnameVerifier());
Dan Dyer
7
Sf.setHostnameVerifier jest przestarzały od 4.1. Alternatywą jest użycie jednego z konstruktorów. Na przykład: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);}
dzięki za zaktualizowaną odpowiedź, przyznałem nowemu gościowi nagrodę za „powitanie”, ale chciałem tylko zaktualizowanych odpowiedzi dla wszystkich!
1
@feelingunwelcome, jasne. Ja też go zagłosowałem :-)
Tarun Lalwani
2
pełna wersja działająca dla Apache HttpClient 4.1.3 (oparta na powyższym kodzie olega, ale nadal wymagała w moim systemie allow_all_hostname_verifier):
Jeśli napotkałeś ten problem podczas korzystania z AmazonS3Client, który osadza Apache HttpClient 4.1, wystarczy zdefiniować właściwość systemową taką jak ta, aby moduł sprawdzania certyfikatów SSL był zrelaksowany:
Jeśli używasz Apache httpClient 4.5.x, spróbuj tego:
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();}
Odpowiedzi:
Musisz utworzyć SSLContext z własnym TrustManager i utworzyć schemat HTTPS przy użyciu tego kontekstu. Oto kod,
źródło
HttpClientBuilder
?Wszystkie pozostałe odpowiedzi były przestarzałe lub nie działały w przypadku HttpClient 4.3.
Oto sposób na zezwolenie na wszystkie nazwy hostów podczas budowania klienta http.
Jeśli używasz wersji 4.4 lub nowszej, zaktualizowane wywołanie wygląda następująco:
źródło
Po prostu musiałem to zrobić z nowszym HttpClient 4.5 i wygląda na to, że wycofali kilka rzeczy od 4.4, więc oto fragment kodu, który działa dla mnie i używa najnowszego interfejsu API:
źródło
Tak dla przypomnienia, istnieje znacznie prostszy sposób osiągnięcia tego samego z HttpClient 4.1
źródło
new SSLSocketFactory((chain, authType) -> true);
Apache HttpClient 4.5.5
Nie użyto żadnego wycofanego interfejsu API.
Prosty weryfikowalny przypadek testowy:
źródło
TrustAllStrategy.INSTANCE
sięTrustSelfSignedStrategy.INSTANCE
w tej odpowiedzi.Dla przypomnienia, przetestowany z httpclient 4.3.6 i kompatybilny z Executorem płynnego api:
źródło
SSLConnectionSocketFactory
używającego goSSLContext
i zdefiniowanie tego w aRegistry<ConnectionSocketFactory>
, jeśli masz zamiar utworzyć plikPoolingHttpClientConnectionManager
. Pozostałe odpowiedzi są bardziej popularne, ale nie działają w HttpClient 4.4.W przypadku Apache HttpClient 4.4:
Jest to wyodrębnione z naszej rzeczywistej implementacji roboczej.
Inne odpowiedzi są popularne, ale w przypadku HttpClient 4.4 nie działają. Spędziłem godziny próbując i wyczerpując możliwości, ale wydaje się, że nastąpiła bardzo duża zmiana API i przeniesienie w 4.4.
Zobacz także nieco pełniejsze wyjaśnienie pod adresem: adresem http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/
Mam nadzieję, że to pomoże!
źródło
Jeśli wszystko, co chcesz zrobić, to pozbyć się błędów nieprawidłowych nazw hostów, możesz po prostu zrobić:
źródło
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Używamy HTTPClient 4.3.5 i wypróbowaliśmy prawie wszystkie rozwiązania, które istnieją w przepływie stosu, ale nic. Po przemyśleniu i rozwiązaniu problemu dochodzimy do następującego kodu, który działa idealnie, po prostu dodaj go przed utworzeniem wystąpienia HttpClient.
źródło
Mając płynną wersję 4.5.2 musiałem wprowadzić następującą modyfikację, aby to działało.
źródło
Tak to zrobiłem -
Inicjalizacja DefaultHTTPClient -
Mock SSL Factory -
Jeśli za serwerem proxy, musisz to zrobić -
źródło
Jako rozszerzenie odpowiedzi ZZ Codera, miło będzie nadpisać zmiennik nazwy hosta.
źródło
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
źródło
Aby zaakceptować wszystkie certyfikaty w HttpClient 4.4.x, możesz użyć poniższej linijki podczas tworzenia httpClient:
źródło
Testowane za pomocą HttpClient 4.5.5 z interfejsem Fluent API
źródło
Poniższy kod działa z
4.5.5
Dane wyjściowe z kodu to
Dane wyjściowe w przeglądarce to
Zastosowany pom jest poniżej
źródło
pełna wersja działająca dla Apache HttpClient 4.1.3 (oparta na powyższym kodzie olega, ale nadal wymagała w moim systemie allow_all_hostname_verifier):
Uwaga Ponownie wyrzucam wszystkie wyjątki, ponieważ tak naprawdę niewiele mogę zrobić, jeśli coś z tego zawiedzie w prawdziwym systemie!
źródło
Jeśli korzystasz z Fluent API , musisz go skonfigurować za pomocą
Executor
:... gdzie
sslContext
jest utworzony SSLContext, jak pokazano w odpowiedzi ZZ Coder .Następnie możesz wykonywać żądania http jako:
Uwaga: testowano z HttpClient 4.2
źródło
Testowane z 4.3.3
}
źródło
Testowane 4.5.4:
źródło
Jeśli napotkałeś ten problem podczas korzystania z AmazonS3Client, który osadza Apache HttpClient 4.1, wystarczy zdefiniować właściwość systemową taką jak ta, aby moduł sprawdzania certyfikatów SSL był zrelaksowany:
-Dcom.amazonaws.sdk.disableCertChecking = true
Udało się psotom
źródło
fwiw, przykład użycia implementacji JAX-RS 2.x „RestEasy” w celu zbudowania specjalnego klienta „zaufaj wszystkim” ...
powiązane zależności Maven
źródło
Jeśli używasz Apache httpClient 4.5.x, spróbuj tego:
źródło