Apache Http 客户端 SSL 证书错误
Posted
技术标签:
【中文标题】Apache Http 客户端 SSL 证书错误【英文标题】:Apache Http Client SSL certificate error 【发布时间】:2014-07-13 06:00:28 【问题描述】:我知道之前有人问过这个问题,但我尝试了所有找到的解决方案,但仍然无法正常工作。
基本上,我正在尝试通过 Apache Http Client (4.3) 获取一些内容,而我正在连接的网站存在一些 SSL 问题。
首先,我收到了 SSLException
和 unrecognized_name
消息。我试图通过将jsse.enableSNIExtension
属性设置为false
来解决这个问题。
然后,我得到了这个异常:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
然后我尝试提供我赢得的SSLFactory
,它将接受所有证书,但我仍然遇到同样的异常。这是我的代码:
private static void sslTest() throws Exception
System.setProperty("jsse.enableSNIExtension", "false");
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, new TrustSelfSignedStrategy())
.useTLS()
.build();
SSLConnectionSocketFactory connectionFactory =
new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
CookieStore cookieStore = new BasicCookieStore();
HttpClientContext context = HttpClientContext.create();
context.setCookieStore(cookieStore);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(connectionFactory)
.setDefaultCookieStore(cookieStore)
.build();
URI uri = new URIBuilder()
.setScheme("https")
.setHost(BASE_URL)
.build();
String responseBody = httpclient.execute(new HttpGet(uri), RESPONSE_HANDLER);
非常感谢所有帮助!
【问题讨论】:
请看我另一个问题的回答:***.com/a/45734000/8477758 这能回答你的问题吗? How to ignore SSL certificate errors in Apache HttpClient 4.0 【参考方案1】:还请注意,信任自签名证书并不意味着信任任何任意证书。
尝试以这种方式设置您的 SSL 上下文:
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null,
new TrustStrategy()
@Override
public boolean isTrusted(final X509Certificate[] chain, final String authType)
throws CertificateException
return true;
)
.useTLS()
.build();
还请注意,通常不加选择地信任证书会首先破坏使用 SSL 的目的。在绝对必要或仅用于测试时使用
【讨论】:
就像一个魅力。使用HttpClientBuilder
这是创建实例的方法 - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext); CloseableHttpClient client = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build();
【参考方案2】:
在 Http 客户端 4.5.2 中:
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null,
new TrustStrategy()
@Override
public boolean isTrusted(final X509Certificate[] chain, final String authType)
throws CertificateException
return true;
).build();
SSLConnectionSocketFactory sslsf;
sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
然后:
HttpClientBuilder builder = HttpClients.custom().setSSLSocketFactory(sslsf);
【讨论】:
【参考方案3】:您的信任库不信任服务器证书。
允许所有主机名是一个 HTTPS 步骤,只有在证书受信任的情况下才能调用该步骤。
【讨论】:
【参考方案4】:以下是 Apache 4x 信任一切
static
// avoid error javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
System.setProperty("jsse.enableSNIExtension", "false");
public static HttpClientBuilder createTrustAllHttpClientBuilder()
try
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, (chain, authType) -> true);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE);
return HttpClients.custom().setSSLSocketFactory(sslsf);
catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e)
throw new IllegalStateException(e);
【讨论】:
以上是关于Apache Http 客户端 SSL 证书错误的主要内容,如果未能解决你的问题,请参考以下文章