项目场景:
提示:本地调试正常:
项目场景:
部署到WebSphere服务器上就会报上述错误;
一度认为是WebSphere服务器上的配置有问题,经过多次偿试,最终解决问题发现和服务配置无关;
测试环境使用HttpClient发送https请求下载附件时报错:
问题描述
提示:项目地址是http,需要访问的地址是https:
因为访问https地址所以默认信任所有证书:
/**
* 创建 HttpClient 客户端代码
* @return org.apache.http.impl.client.CloseableHttpClient
* @Author xianzi
* @CreateTime 2022/10/17 15:53
* @Description 信任所有证书
**/
public static CloseableHttpClient createSSLClientDefault() {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
//"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"
// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv1.2"}, null, hostnameVerifier);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return HttpClients.createDefault();
}
使用httpclient发送https请求下载附件时报错:
javax.net.ssl.SSLHandshakeException: Received fatal alert: unrecognized_name
at com.ibm.jsse2.i.a(i.java:31)
~[?:8.0 build 201512221
at com.ibm.jsse2.i.ali.java:43)~?:8.0 build 201512221
at com.ibm.jsse2.as.blas.java:816) -?:8.0 build 201512221
at com.ibm.jsse2.as.alas. java: 752)
~?:8.0 build 201512221
at
com.ibm.jsse2.as.i(as.java:130)
~?:8.0 build 201512221
at
com.ibm.jssez.as.a(as.java:483) ~ ?:8.0 build 201512221
com.ibm.jsse2.as.startHandshake(as.java:160)
~[?:8.0 build 201512221
附图: 此处看报错信息曾怀疑是服务器使用的是ibmjdk导致的错误,但是后续解决问题之后证实这个方向是错误的
原因分析:
https认证方式分为2种(单向认证、双向认证):
单向认证:
单向认证一般是指客户端确认服务端身份(也就是我常用的不安全认证模式)
上面代码也确实证实了单向认证请求https是没有问题的;双向认证:
双向认证则是指在客户端需要确认服务端身份的同时,服务端也需要确认客户端的身份。
接下来也是我解决此错误的原因
网上搜索到的解决方案,偿试无效的有
一、设置系统属性,在启动类加上下列代码无效:
System.setProperty ("jsse.enableSNIExtension", "false");
二、在JVM启动命令中加入指令无效:
-Djsse.enableSNIExtension=false
三、将上面指令配置到tomcat中(没有偿试过)
最终也不是通过此方案解决错误
解决方案:
请求双向认证的https地址时,客户端需要初始化证书及证书版本,客户端会根据根证书生成携带公钥的子证书发服务端发送二次握手,服务端会验证客户端的请求是否合法,至此问题解决.代码如下:
文章来源:https://www.toymoban.com/news/detail-446074.html
/**
* 双向认证请求客户端创建
* @Author xiangzi
* @CreateTime 2022/10/17 16:29
*/
public static CloseableHttpClient creatTwoWayHttpClient() {
try {
CloseableHttpClient httpclient;
// SSLContext ctx = SSLContexts.createSystemDefault();
// SSLConnectionSocketFactory fac =
// new SSLConnectionSocketFactory(ctx, new String[] {"TLSv1.2"}, null,
// SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
// httpclient = HttpClientBuilder.create().setSSLSocketFactory(fac).build();
SSLContext ctx = SSLContexts.custom().useProtocol("TLSv1.2").build();
httpclient = HttpClientBuilder.create().setSslcontext(ctx).build();
// HttpPost httpPost = new HttpPost(url);
// CloseableHttpResponse resp = httpclient.execute(httpPost);
// System.out.println("===SSL版本: "+v+"测试附件test====结束"+resp.toString());
return httpclient;
} catch (Exception e) {
e.printStackTrace();
}
return HttpClients.createDefault();
}
暂未实现 单向验证和双向验证请求兼容初始化客户端代码,只是在使用时加了一个参数区分;代码如下:文章来源地址https://www.toymoban.com/news/detail-446074.html
/**
* @param isTwoWayAuthentication true 表示发送HTTPS请求对方为双向验证域名
* 创建 HttpClient 客户端代码
* @return org.apache.http.impl.client.CloseableHttpClient
* @Author xianzi
* @CreateTime 2022/10/17 15:53
* @Description 信任所有证书
**/
public static CloseableHttpClient createSSLClientDefault(Boolean isTwoWayAuthentication) {
try {
if (isTwoWayAuthentication) {
return creatTwoWayHttpClient();
}
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
//"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"
// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv1.2"}, null, hostnameVerifier);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return HttpClients.createDefault();
}
到了这里,关于https请求报错:javax.net.ssl.SSLHandshakeException:Received fatal alert: unrecognized_name 的解决过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!