Apache HttpClient 4.3에서 SSL 인증서 무시


102

Apache HttpClient 4.3에 대한 SSL 인증서 (모두 신뢰)를 무시하는 방법은 무엇입니까?

내가 찾은 모든 답변은 이전 버전을 처리하고 API가 변경되었습니다.

관련 :

편집하다:

  • 테스트 목적으로 만 사용됩니다. 아이들, 집에서 (또는 프로덕션에서) 시도하지 마십시오.

답변:


146

아래 코드는 자체 서명 된 인증서를 신뢰하는 데 사용됩니다. 클라이언트를 만들 때 TrustSelfSignedStrategy 를 사용해야합니다 .

SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
        sslsf).build();

HttpGet httpGet = new HttpGet("https://some-server");
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);
} finally {
    response.close();
}

나는 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER의도적으로 포함하지 않았습니다 . 핵심은 자체 서명 된 인증서로 테스트 할 수 있도록하여 인증 기관에서 적절한 인증서를 획득 할 필요가 없다는 것입니다. 올바른 호스트 이름을 사용하여 자체 서명 된 인증서를 쉽게 만들 수 있으므로 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER플래그 를 추가하는 대신 그렇게하십시오 .


8
HttpClientBuilder와 함께 작동하도록 생성자에 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER 인수를 추가해야했습니다 (holmis83의 vasekt 응답에서 언급했듯이).
dejuknow


2
또한 ALLOW_ALL_HOSTNAME_VERIFIER를 사용해야했습니다. SSLConnectionSocketFactory (builder.build (), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
표시 이름

이 코드는 인수와 함께 사용되지 않는 생성자를 사용 하지 않고 위해 작동합니다SSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
user11153

사용하고 있던 클래스에 대한 전체 참조를 지정했으면합니다. 호출 된 여러 클래스 SSLContextBuilder가 Idea에 의해 발견되었습니다.
MasterMind

91

위의 PoolingHttpClientConnectionManager 절차가 작동하지 않는 경우 사용자 지정 SSLContext가 무시됩니다. PoolingHttpClientConnectionManager를 생성 할 때 생성자에서 socketFactoryRegistry를 전달해야합니다.

SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        return true;
    }
});
SSLContext sslContext = builder.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslContext, new X509HostnameVerifier() {
            @Override
            public void verify(String host, SSLSocket ssl)
                    throws IOException {
            }

            @Override
            public void verify(String host, X509Certificate cert)
                    throws SSLException {
            }

            @Override
            public void verify(String host, String[] cns,
                    String[] subjectAlts) throws SSLException {
            }

            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        });

Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
        .<ConnectionSocketFactory> create().register("https", sslsf)
        .build();

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
        socketFactoryRegistry);
CloseableHttpClient httpclient = HttpClients.custom()
        .setConnectionManager(cm).build();

11
자체 X509HostnameVerifier를 빌드하는 대신 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER를 사용할 수 있습니다.
holmis83

@ rich95에 의해 아래에 표시된 것처럼 HttpClients의 기본값은 PoolingHttpClient를 제공하는 것이므로 매우 자주 관련됩니다. 나는 이것이 필요하다는 것을 발견하기 전에 이러한 답변 중 상당 부분을 시도해야했습니다.
SunSear

1
이를 WebSphere에 적용하려고 시도한 결과 "java.security.KeyStoreException : IBMTrustManager : 신뢰 저장소 액세스 문제 java.io.IOException : 유효하지 않은 키 저장소 형식"이 발생했습니다. 패스가 필요하지 않도록하려면 KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultType ()); 대신 널 (null)의 builder.loadTrustMaterial에
게오르기 Gobozov

1
사실과 HttpClient를 4.5, 모두 HttpClients.custom().setConnectionManager(cm).build()HttpClients.custom().setSSLSocketFactory(connectionFactory).build()당신이 만들 필요가 없습니다, 작동합니다PoolingHttpClientConnectionManager
soulmachine

이 생성 한 후 PoolingHttpClientConnectionManager를 사용하는 방법, 내 코드가 작동하지만 난 알고 싶어 연결 풀링 작업을 수행 여부
Labeo

34

@mavroprovato의 답변에 추가로 자체 서명이 아닌 모든 인증서를 신뢰하려면 (코드 스타일로)

builder.loadTrustMaterial(null, new TrustStrategy(){
    public boolean isTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {
        return true;
    }
});

또는 (내 코드에서 직접 복사하여 붙여 넣기) :

import javax.net.ssl.SSLContext;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.ssl.SSLContexts;

// ...

        SSLContext sslContext = SSLContexts
                .custom()
                //FIXME to contain real trust store
                .loadTrustMaterial(new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain,
                        String authType) throws CertificateException {
                        return true;
                    }
                })
                .build();

호스트 이름 확인도 건너 뛰려면 다음을 설정해야합니다.

    CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
            sslsf).setSSLHostnameVerifier( NoopHostnameVerifier.INSTANCE).build();

게다가. (ALLOW_ALL_HOSTNAME_VERIFIER는 더 이상 사용되지 않습니다.)

필수 경고 : 실제로 이렇게해서는 안됩니다. 모든 인증서를 수락하는 것은 나쁜 일입니다. 그러나이를 수행하려는 드문 사용 사례가 있습니다.

이전에 제공된 코드에 대한 참고 사항으로 httpclient.execute ()에서 예외가 발생하더라도 응답을 닫고 싶을 것입니다.

CloseableHttpResponse response = null;
try {
    response = httpclient.execute(httpGet);
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);
}
finally {
    if (response != null) {
        response.close();
    }
}

위의 코드는

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

관심있는 분들을 위해 여기에 제 전체 테스트 세트가 있습니다.

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class TrustAllCertificatesTest {
    final String expiredCertSite = "https://expired.badssl.com/";
    final String selfSignedCertSite = "https://self-signed.badssl.com/";
    final String wrongHostCertSite = "https://wrong.host.badssl.com/";

    static final TrustStrategy trustSelfSignedStrategy = new TrustSelfSignedStrategy();
    static final TrustStrategy trustAllStrategy = new TrustStrategy(){
        public boolean isTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            return true;
        }
    };

    @Test
    public void testSelfSignedOnSelfSignedUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustSelfSignedStrategy);
    }
    @Test(expected = SSLHandshakeException.class)
    public void testExpiredOnSelfSignedUsingCode() throws Exception {
        doGet(expiredCertSite, trustSelfSignedStrategy);
    }
    @Test(expected = SSLPeerUnverifiedException.class)
    public void testWrongHostOnSelfSignedUsingCode() throws Exception {
        doGet(wrongHostCertSite, trustSelfSignedStrategy);
    }

    @Test
    public void testSelfSignedOnTrustAllUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustAllStrategy);
    }
    @Test
    public void testExpiredOnTrustAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy);
    }
    @Test(expected = SSLPeerUnverifiedException.class)
    public void testWrongHostOnTrustAllUsingCode() throws Exception {
        doGet(wrongHostCertSite, trustAllStrategy);
    }

    @Test
    public void testSelfSignedOnAllowAllUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }
    @Test
    public void testExpiredOnAllowAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }
    @Test
    public void testWrongHostOnAllowAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }

    public void doGet(String url, TrustStrategy trustStrategy, HostnameVerifier hostnameVerifier) throws Exception {
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).setSSLHostnameVerifier(hostnameVerifier).build();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpGet);
        try {
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    }
    public void doGet(String url, TrustStrategy trustStrategy) throws Exception {

        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).build();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpGet);
        try {
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    }
}

( github의 작업 테스트 프로젝트 )


1
HttpClient # execute는 예외가 발생하는 경우 null 응답 개체를 반환하지 않습니다. 또한 스톡 HttpClient 구현은 요청 실행 중 예외가 발생하는 경우 임대 연결과 같은 모든 시스템 리소스의 자동 할당 해제를 보장합니다. mavroprovato에서 사용하는 예외 처리는 완벽하게 적합합니다.
ok2c 2013

@oleg Closable 인터페이스 의 요점은 "Close [...] 스트림과 관련된 시스템 리소스를 해제하는 것입니다. 스트림이 이미 닫혀 있으면이 메서드를 호출해도 효과가 없습니다." 따라서 필요하지 않더라도 사용하는 것이 가장 좋습니다. 또한 null 응답을 반환하는 주석을 이해하지 못합니다. 물론 예외가 발생하면 아무것도 반환하지 않습니다.
eis

1
아파치 HttpClient를 결코 이제까지 null 또는 부분적으로 초기화 응답 객체를 반환하지 않습니다. 이것은 #close가 호출되는 횟수와 관련이 없지만 finally 절에서 완전히 불필요한 null 검사
ok2c

@oleg 및 내가 제공 한 코드는 null 또는 부분적으로 초기화 된 응답 객체를 반환하거나 그러한 경우를 확인한다고 가정하지 않습니다. 무슨 말을하는지 모르겠어요?
eis

1
[ sigh ] HttpResponse가 null 일 수 없으며 예외의 경우 #execute 메소드가 응답을 반환하지 않고 종료된다는 점을 감안할 때 완전히 불필요합니다. ;-)
ok2c

22

vasekt의 답변에 대한 작은 추가 사항 :

SocketFactoryRegistry와 함께 제공된 솔루션은 PoolingHttpClientConnectionManager를 사용할 때 작동합니다.

그러나 일반 http를 통한 연결은 더 이상 작동하지 않습니다. http 프로토콜에 대한 PlainConnectionSocketFactory를 추가로 추가하여 다시 작동하도록해야합니다.

Registry<ConnectionSocketFactory> socketFactoryRegistry = 
  RegistryBuilder.<ConnectionSocketFactory> create()
  .register("https", sslsf)
  .register("http", new PlainConnectionSocketFactory()).build();

http프로토콜이 PlainConnectionSocketFactory 기본적으로 사용 하고 있다고 생각 합니다 . 나는 등록 만 https했고 httpclient여전히 일반 HTTP URL을 얻을 수 있습니다. 그래서이 단계가 필요하지 않다고 생각합니다.
soulmachine 2015-09-04

@soulmachine은하지 않습니다에 대한PoolingHttpClientConnectionManager
amseager

15

다양한 옵션을 시도한 후 다음 구성이 http 및 https 모두에서 작동했습니다.

        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(),SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);


        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", sslsf)
                .build();


        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
        cm.setMaxTotal(2000);//max connection


        //System.setProperty("jsse.enableSNIExtension", "false"); //""
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .setConnectionManager(cm)
                .build();

http-client 4.3.3을 사용하고 있습니다.-

compile 'org.apache.httpcomponents:httpclient:4.3.3'


1
포괄적이고 완벽하게 작동하는 예제를 제공해 주셔서 감사합니다! 나는 이전 솔루션으로 여러 문제를 겪었고 이것은 엄청난 도움이되었습니다. 또한 동일한 이름을 가진 여러 클래스가 있으므로 import 문을 제공하여 혼란을 더했습니다.
helmy

8

더 간단하고 짧은 작업 코드 :

우리는 HTTPClient 4.3.5를 사용하고 있으며 거의 ​​모든 솔루션이 stackoverflow에 존재하지만 아무것도 시도하지 않았습니다. 문제를 생각하고 파악한 후 완벽하게 작동하는 다음 코드가 나오면 HttpClient 인스턴스를 만들기 전에 추가합니다.

포스트 요청을 할 때 사용하는 방법 ...

SSLContextBuilder builder = new SSLContextBuilder();
    builder.loadTrustMaterial(null, new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            return true;
        }
    });

    SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(builder.build(),
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSF).build();
    HttpPost postRequest = new HttpPost(url);

계속해서 HttpPost 인스턴스를 일반 형식으로 호출하고 사용합니다.


헤더에 데이터를 게시하려면 어떻게해야합니까? 우리가했던 경우, 참조 HTTP 잘못된 요청 / 1.1 400

6

다음은 "curl --insecure"에 해당하는 위 기술의 작동 증류입니다.

HttpClient getInsecureHttpClient() throws GeneralSecurityException {
    TrustStrategy trustStrategy = new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) {
            return true;
        }
    };

    HostnameVerifier hostnameVerifier = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    return HttpClients.custom()
            .setSSLSocketFactory(new SSLConnectionSocketFactory(
                    new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(),
                    hostnameVerifier))
            .build();
}

5

http 클라이언트 4.5를 사용할 때 모든 호스트 이름 (테스트 목적)을 허용하려면 javasx.net.ssl.HostnameVerifier를 사용해야했습니다. 내가 한 일은 다음과 같습니다.

CloseableHttpClient httpClient = null;
    try {
        SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
        sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());

        HostnameVerifier hostnameVerifierAllowAll = new HostnameVerifier() 
            {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
            new AuthScope("192.168.30.34", 8443),
            new UsernamePasswordCredentials("root", "password"));

        httpClient = HttpClients.custom()
            .setSSLSocketFactory(sslSocketFactory)
            .setDefaultCredentialsProvider(credsProvider)
            .build();

        HttpGet httpGet = new HttpGet("https://192.168.30.34:8443/axis/services/getStuff?firstResult=0&maxResults=1000");

        CloseableHttpResponse response = httpClient.execute(httpGet);

        int httpStatus = response.getStatusLine().getStatusCode();
        if (httpStatus >= 200 && httpStatus < 300) { [...]
        } else {
            throw new ClientProtocolException("Unexpected response status: " + httpStatus);
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    finally {
        try {
            httpClient.close();
        } catch (IOException ex) {
            logger.error("Error while closing the HTTP client: ", ex);
        }
    }

HostnameVerifier의 구현으로 HTTPClient 4.5의 문제가 해결되었습니다.
digz6666 2011

람다 (JDK1.8)을 좋아하는 사람들을 위해, 교체 할 수 있습니다 SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);. 익명 클래스를 피하고 코드를 좀 더 읽기 쉽게 만듭니다.
Vielinko 2017 년

3

위에 PoolingHttpClientConnectionManager와 함께 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); 당신이 원하는 경우 비동기 HttpClient를 사용하여 PoolingNHttpClientConnectionManager다음과 유사 shoudl 코드를

SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        return true;
    }
});
SSLContext sslContext = builder.build();
SchemeIOSessionStrategy sslioSessionStrategy = new SSLIOSessionStrategy(sslContext, 
                new HostnameVerifier(){
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;// TODO as of now allow all hostnames
            }
        });
Registry<SchemeIOSessionStrategy> sslioSessionRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create().register("https", sslioSessionStrategy).build();
PoolingNHttpClientConnectionManager ncm  = new PoolingNHttpClientConnectionManager(new DefaultConnectingIOReactor(),sslioSessionRegistry);
CloseableHttpAsyncClient asyncHttpClient = HttpAsyncClients.custom().setConnectionManager(ncm).build();
asyncHttpClient.start();        

3

을 사용하는 경우 HttpClient 4.5.x코드는 다음과 유사 할 수 있습니다.

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
        TrustSelfSignedStrategy.INSTANCE).build();
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
        sslContext, NoopHostnameVerifier.INSTANCE);

HttpClient httpClient = HttpClients.custom()
                                   .setDefaultCookieStore(new BasicCookieStore())
                                   .setSSLSocketFactory(sslSocketFactory)
                                   .build();

나를 위해 일하지 않았습니다. HttpClient : 4.5.5를 사용하고 있습니다. 및 HttpCore 4.4.9
Vijay Kumar

2
class ApacheHttpClient {

    /***
     * This is a https get request that bypasses certificate checking and hostname verifier.
     * It uses basis authentication method.
     * It is tested with Apache httpclient-4.4.
     * It dumps the contents of a https page on the console output.
     * It is very similar to http get request, but with the additional customization of
     *   - credential provider, and
     *   - SSLConnectionSocketFactory to bypass certification checking and hostname verifier.
     * @param path String
     * @param username String
     * @param password String
     * @throws IOException
     */
    public void get(String path, String username, String password) throws IOException {
        final CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCredentialsProvider(createCredsProvider(username, password))
                .setSSLSocketFactory(createGenerousSSLSocketFactory())
                .build();

        final CloseableHttpResponse response = httpClient.execute(new HttpGet(path));
        try {
            HttpEntity entity = response.getEntity();
            if (entity == null)
                return;
            System.out.println(EntityUtils.toString(entity));
        } finally {
            response.close();
            httpClient.close();
        }
    }

    private CredentialsProvider createCredsProvider(String username, String password) {
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
        return credsProvider;
    }

    /***
     * 
     * @return SSLConnectionSocketFactory that bypass certificate check and bypass HostnameVerifier
     */
    private SSLConnectionSocketFactory createGenerousSSLSocketFactory() {
        SSLContext sslContext;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{createGenerousTrustManager()}, new SecureRandom());
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
        return new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    }

    private X509TrustManager createGenerousTrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] cert, String s) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] cert, String s) throws CertificateException {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
    }
}

2

Apache HTTP 클라이언트의 모든 인증서 신뢰

TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
                        public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                        }
                        public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                        }
                    }
                };

          try {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sc);
                httpclient = HttpClients.custom().setSSLSocketFactory(
                        sslsf).build();
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

이것은 httpclient 4.5.9에서 잘 작동했습니다. 전체 콘텐츠를 복사하여 붙여 넣으십시오.
sathya

1

(나는 vasekt의 답변에 직접 의견을 추가했지만 평판 포인트가 충분하지 않습니다 (논리가 확실하지 않음)

어쨌든 ... 내가 말하고 싶은 것은 명시 적으로 PoolingConnection을 생성 / 요구하지 않더라도 연결을 얻지 못한다는 의미는 아닙니다.

원래 솔루션이 저에게 효과가 없었던 이유를 알아 내려고 미쳐 가고 있었지만 "내 케이스에 적용되지 않았기 때문에"바스 텍의 대답을 무시했습니다.-틀 렸습니다!

나는 낮을 때 내 스택 추적을 쳐다보고 있었고 그 중간에 PoolingConnection을 보았다. Bang-그의 추가와 성공에 지쳤습니다 !! (우리 데모는 내일이고 필사적이었습니다) :-)


0

SSL 인증 확인없이 HttpClient 인스턴스를 얻기 위해 다음 코드 스 니펫을 사용할 수 있습니다.

private HttpClient getSSLHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

        LogLoader.serverLog.trace("In getSSLHttpClient()");

        SSLContext context = SSLContext.getInstance("SSL");

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        context.init(null, new TrustManager[] { tm }, null);

        HttpClientBuilder builder = HttpClientBuilder.create();
        SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(context);
        builder.setSSLSocketFactory(sslConnectionFactory);

        PlainConnectionSocketFactory plainConnectionSocketFactory = new PlainConnectionSocketFactory();
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslConnectionFactory).register("http", plainConnectionSocketFactory).build();

        PoolingHttpClientConnectionManager ccm = new PoolingHttpClientConnectionManager(registry);
        ccm.setMaxTotal(BaseConstant.CONNECTION_POOL_SIZE);
        ccm.setDefaultMaxPerRoute(BaseConstant.CONNECTION_POOL_SIZE);
        builder.setConnectionManager((HttpClientConnectionManager) ccm);

        builder.disableRedirectHandling();

        LogLoader.serverLog.trace("Out getSSLHttpClient()");

        return builder.build();
    }

0

수중 음파 탐지기 보안 경고를 수정하기 위해 위의 @divbyzero에서 답변을 약간 수정했습니다.

CloseableHttpClient getInsecureHttpClient() throws GeneralSecurityException {
            TrustStrategy trustStrategy = (chain, authType) -> true;

            HostnameVerifier hostnameVerifier = (hostname, session) -> hostname.equalsIgnoreCase(session.getPeerHost());

            return HttpClients.custom()
                    .setSSLSocketFactory(new SSLConnectionSocketFactory(new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(), hostnameVerifier))
                    .build();
        }

0

처음에는 신뢰 전략을 사용하여 localhost를 비활성화 할 수 있었고 나중에 NoopHostnameVerifier를 추가했습니다. 이제 localhost와 모든 컴퓨터 이름 모두에서 작동합니다.

SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(null, new TrustStrategy() {

            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }

        }).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext, NoopHostnameVerifier.INSTANCE);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.