java SSLContextImpl 未初始化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41047344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 05:38:52  来源:igfitidea点击:

SSLContextImpl is not initialized

javaapache-httpclient-4.xtls1.2sslcontext

提问by Shantanoo K

Below are my configurations

下面是我的配置

java version "1.8.0_101" Java(TM) SE Runtime Environment (build 1.8.0_101-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

java 版本“1.8.0_101”Java(TM) SE 运行时环境(构建 1.8.0_101-b13)Java HotSpot(TM) 64 位服务器 VM(构建 25.101-b13,混合模式)

Using Apache httpclient v4.4 to call the Restful service, The service URL has a valid certificate (SHA2)

使用Apache httpclient v4.4调用Restful服务,服务URL有有效证书(SHA2)

Using apache httpclient we are calling the service. Below is the code

我们使用 apache httpclient 调用服务。下面是代码

private static CloseableHttpClient appHttpClient() throws Exception {
    if (null != httpclient) {
        return httpclient;
    }
    final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
            .<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(trustAllSSLContext())).build();

    final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
    cm.setMaxTotal(HTTP_MAX_CON);
    cm.setDefaultMaxPerRoute(HTTP_CON_ROUTE);

    final RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(HTTP_CON_TO)
            .setConnectionRequestTimeout(HTTP_REQ_CON_TO).setSocketTimeout(HTTP_SO_TO).build();

    // final SSLConnectionSocketFactory factory = new
    // SSLConnectionSocketFactory(getSSLContext());

    httpclient = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build();

    return httpclient;
}

public static SSLContext trustAllSSLContext() throws Exception {
    if (sslContext != null) {
        return sslContext;
    }
    sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(null, null, null);
    System.out.println(
            "SSLContext :: Protocol :: " + sslContext.getProtocol() + " Provider :: " + sslContext.getProvider());
    return sslContext;
}

The service call is failing intermittently, there is batch process which calls our services in a loop, say 30 calls to services so some of them are failing and some of them are successful, for failed calls we are getting below exception.

服务调用间歇性失败,有一个批处理循环调用我们的服务,比如对服务的 30 次调用,所以其中一些失败了,其中一些成功了,对于失败的调用,我们得到以下异常。

java.lang.IllegalStateException: SSLContextImpl is not initialized
   at sun.security.ssl.SSLContextImpl.engineGetSocketFactory(SSLContextImpl.java:181)
   at javax.net.ssl.SSLContext.getSocketFactory(SSLContext.java:294)
   at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>(SSLConnectionSocketFactory.java:262)
   at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>(SSLConnectionSocketFactory.java:205)
   at com.wdpr.payment.helper.HttpHelper.appHttpClient(HttpHelper.java:63)
   at com.wdpr.payment.helper.HttpHelper.makePostCall(HttpHelper.java:142)...

Any one has any idea why it is failing for this exception intermittently.

任何人都知道为什么它会间歇性地失败此异常。

回答by louisgab

In the code snippets I found online,

在我在网上找到的代码片段中,

sslContext = SSLContext.getInstance("");

was called with "SSL" instead of "TLSv1.2".

被称为“SSL”而不是“TLSv1.2”。

To force ssl sockets to use TLSv1.2, I used How to force Commons HTTPClient 3.1 to use TLS 1.2 only for HTTPS?

为了强制 ssl 套接字使用 TLSv1.2,我使用了 How to force Commons HTTPClient 3.1 to use TLS 1.2 only for HTTPS?

(edit)

(编辑)

On a possibly related note, when using Http Commons MultiThreadedHttpConnectionManager, we have to call

在一个可能相关的注释中,当使用 Http Commons MultiThreadedHttpConnectionManager 时,我们必须调用

manager.closeIdleConnections(10000); 
manager.deleteClosedConnections();

after each http call, otherwise we experiment some connection failures every N calls.

在每次 http 调用之后,否则我们每 N 次调用就会尝试一些连接失败。

回答by Alex Chernyshev

If 'The service URL has a valid certificate' is true - just remove all SSL-related customizations.

如果“服务 URL 具有有效证书”为真 - 只需删除所有与 SSL 相关的自定义设置。

This one ( trust them all approach ):

这个(相信他们所有的方法):

new SSLConnectionSocketFactory(trustAllSSLContext())

is actually a hack for non-valid certificates, as quick fix - try to add 'synchronized' to trustAllSSLContextmethod.

实际上是对无效证书的一种黑客攻击,作为快速修复 - 尝试将“ synchronized”添加到trustAllSSLContext方法中。