web-dev-qa-db-ja.com

Apache HTTPClient 4.5で自己署名証明書を無視する

すべての証明書を受け入れる、および/または自己署名証明書を受け入れるApache HTTPClientバージョン4.5を使用する(チュートリアルリンク ここ

私は、SOに関するたくさんの投稿からこの問題の解決策を講じてきました。これまでのところ、どれも機能していません。

このエラーが発生し続けます:Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake

Apache Docs:

関連するStackOverflowの質問-これが私が試したソリューションのリンクです:

これらすべての例では、前に定義したCookieストアとプロキシ資格情報プロバイダーも渡しています。これらは機能しています。SSLサポートを追加しようとしています。

#1を試す

SSLContextBuilderで自分のsslコンテキストを作成し、TrustSelfSignedStrategyですべての自己署名戦略を信頼します。

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

CloseableHttpClient httpclient = HttpClients.custom()
    .setDefaultCredentialsProvider(credsProvider)
    .setDefaultCookieStore(cookieStore)
    .setSSLSocketFactory(sslsf)
    .build();

[〜#〜]結果[〜#〜]:機能しませんでした。 Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake

#2を試す

上記と同じですが、PoolingHttpClientConnectionManagerを追加します

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

CloseableHttpClient httpclient = HttpClients.custom()
    .setDefaultCredentialsProvider(credsProvider)
    .setDefaultCookieStore(cookieStore)
    .setSSLSocketFactory(sslsf)
    .setConnectionManager(cm)
    .build();

[〜#〜]結果[〜#〜]:機能しませんでした。 Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake

#3を試す

TrustStrategyをオーバーライドして、すべての証明書を受け入れるだけです(これは推奨されません)。

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);

CloseableHttpClient httpclient = HttpClients.custom()
    .setDefaultCredentialsProvider(credsProvider)
    .setDefaultCookieStore(cookieStore)
    .setSSLSocketFactory(sslsf)
    .build();

[〜#〜]結果[〜#〜]:機能しませんでした。 Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake

#4を試す

この答え から役立つものを見つけました:

バージョン4.5以降、HttpClientはデフォルトでSSLv3プロトコルバージョンを無効にします

ここに彼が与えた解決策があります:

SSLContext sslcontext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
        sslcontext, new String[] { "TLSv1", "SSLv3" }, null,
        SSLConnectionSocketFactory.getDefaultHostnameVerifier());

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

httpclient = HttpClients.custom()
    .setDefaultCredentialsProvider(credsProvider)
    .setDefaultCookieStore(cookieStore)
    .setSSLSocketFactory(sslConnectionSocketFactory)
    .setConnectionManager(cm)
    .build();

[〜#〜]結果[〜#〜]:機能しませんでした。 Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake

11
Katie

上記のアプローチの1つは自己署名証明書の場合に機能するはずですが、奇妙なことに、すべてのアプローチで同じ例外が発生します。

SSLセッションの確立中またはハンドシェイクプロトコルがクライアントでもサーバーでも受け入れられていないように感じます。

ここでの最良の解決策は、アプリケーションをデバッグすることです。

Tomcatの場合は、-Djavax.net.debug = allをsetenv.shまたはsetenv.batファイルに追加してから、サーバーを再起動します。

または このチュートリアル に従ってください。

OPはSSLに接続するときにポートを変更する必要があるだけです。

//For HTTPS
HttpHost httpstarget = new HttpHost("mysite.com", 443, "https");

//For HTTP
HttpHost httptarget = new HttpHost("mysite.com", 80, "http");
3
Azim

私はApache HttpClient 4.5.3を使用していますが、上記の解決策はどれも役に立ちませんでした。いつもエラーが出ました

PKIXパスの構築に失敗しました

私は http://www.baeldung.com/httpclient-ssl で解決策を見つけました

これが私のコードです:

try {
    SSLContext sslContext = new SSLContextBuilder()
            .loadTrustMaterial(null, (certificate, authType) -> true).build();
    httpClient = HttpClients.custom().setSSLContext(sslContext)
            .setSSLHostnameVerifier(new NoopHostnameVerifier())
            .build();
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
    e.printStackTrace();
}
10
Martin Pabst

多くの場合、自己署名証明書をサポートする必要があるだけでなく、マルチスレッド要求を呼び出す必要があるため、プーリング接続マネージャーを使用します。ここに私がそれをする方法があります:

private CloseableHttpClient newClient() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
    SSLContext context = SSLContexts.custom()
            .loadTrustMaterial(TrustSelfSignedStrategy.INSTANCE)
            .build();

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

    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);

    return HttpClients.custom()
            .setConnectionManager(connectionManager)
            .build();
}
6
Yaniv Nahoum
public static HttpClient newClient() {
        SSLContext sslcontext = null;
        try {
            sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
        } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
            e.printStackTrace();
        }

        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext,
                (s, sslSession) -> true);

        return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory)
                .build();
    }
2
Oleg Maksymuk