javax.net.ssl.SSLPeerUnverifiedException: Hostname 192.168.13.13 not verified:
前言:
之前需求推送数据是采用http:192.168.13.13:8000 后面业务需求修改为
https:192.168.13.13:443
修改后推送数据到第三方报以下异常,
https://192.168.13.13:443/xxx/xxx/datapaaapi/planwork/api/xxx/xxx/inputRet报以下异常
javax.net.ssl.SSLPeerUnverifiedException: Hostname 192.168.13.13 not verified:
certificate: sha256/KOCrAFFGwfP/6ZUw1OJHLJLDJLDSAV7qxmUv6HEh2mKUrTs0=
DN: CN=.dfdsdcom.com.cn, O=中国xxxx有限公司浙江分公司, L=杭州市, ST=浙江省, C=CN
subjectAltNames: [.dfdsdcom.com.cn, zjtelecom.com.cn]
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:389)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
at okhttp3.internal.connection.RealCall.initExchange
o
k
h
t
t
p
(
R
e
a
l
C
a
l
l
.
k
t
:
255
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
c
o
n
n
e
c
t
i
o
n
.
C
o
n
n
e
c
t
I
n
t
e
r
c
e
p
t
o
r
.
i
n
t
e
r
c
e
p
t
(
C
o
n
n
e
c
t
I
n
t
e
r
c
e
p
t
o
r
.
k
t
:
32
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
h
t
t
p
.
R
e
a
l
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
.
p
r
o
c
e
e
d
(
R
e
a
l
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
.
k
t
:
109
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
c
a
c
h
e
.
C
a
c
h
e
I
n
t
e
r
c
e
p
t
o
r
.
i
n
t
e
r
c
e
p
t
(
C
a
c
h
e
I
n
t
e
r
c
e
p
t
o
r
.
k
t
:
95
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
h
t
t
p
.
R
e
a
l
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
.
p
r
o
c
e
e
d
(
R
e
a
l
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
.
k
t
:
109
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
h
t
t
p
.
B
r
i
d
g
e
I
n
t
e
r
c
e
p
t
o
r
.
i
n
t
e
r
c
e
p
t
(
B
r
i
d
g
e
I
n
t
e
r
c
e
p
t
o
r
.
k
t
:
83
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
h
t
t
p
.
R
e
a
l
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
.
p
r
o
c
e
e
d
(
R
e
a
l
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
.
k
t
:
109
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
h
t
t
p
.
R
e
t
r
y
A
n
d
F
o
l
l
o
w
U
p
I
n
t
e
r
c
e
p
t
o
r
.
i
n
t
e
r
c
e
p
t
(
R
e
t
r
y
A
n
d
F
o
l
l
o
w
U
p
I
n
t
e
r
c
e
p
t
o
r
.
k
t
:
76
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
h
t
t
p
.
R
e
a
l
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
.
p
r
o
c
e
e
d
(
R
e
a
l
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
.
k
t
:
109
)
a
t
o
k
h
t
t
p
3.
i
n
t
e
r
n
a
l
.
c
o
n
n
e
c
t
i
o
n
.
R
e
a
l
C
a
l
l
.
g
e
t
R
e
s
p
o
n
s
e
W
i
t
h
I
n
t
e
r
c
e
p
t
o
r
C
h
a
i
n
okhttp(RealCall.kt:255) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain
okhttp(RealCall.kt:255)atokhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)atokhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)atokhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)atokhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)atokhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)atokhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)atokhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)atokhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)atokhttp3.internal.connection.RealCall.getResponseWithInterceptorChainokhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
at com.xxx.xxx.utils.PushInspectionStatisticsUtils.pushTaskInventoryFormWorkPlan(PushInspectionStatisticsUtils.java:39)
at
错误大概意思是:
遇到的问题是由于SSL证书验证失败,具体错误信息是 javax.net.ssl.SSLPeerUnverifiedException: Hostname 192.168.13.13 not verified。这是因为HTTPS请求需要验证服务器的SSL证书,并且检查服务器的主机名与证书中的主机名是否匹配。在你的情况中,证书的 subjectAltNames 中并没有包含你访问的 192.168.13.13 IP 地址,而是包含了 .dfdsdcom.com.cn 和 dfdsdcom.com.cn。
代码如下:
package com.xxx.xx.xx.utils;
import com.alibaba.fastjson.JSON;
import com.xx.xx.xx.entity.bo.MajorBo;
import com.xx.xx.xx.entity.bo.xxx;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.util.CollectionUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
/**
* @author laoxu
*/
@Slf4j
public class PushInspectionStatisticsUtils {
public static PushInventoryResponseBo pushTaskInventoryFormWorkPlan(MajorBo majorBo) {
PushInventoryResponseBo responseBo = new PushInventoryResponseBo ();
// 1.创建okhttpClient
OkHttpClient client = new OkHttpClient();
// 2.构建请求头
MediaType mediaType = MediaType.parse("application/json;charset=UTF-8");
String jsonBody = JSON.toJSONString(majorBo);
RequestBody requestBody = RequestBody.create(jsonBody, mediaType);
// 3.封装请求头
Request request = new Request.Builder().url("http://192.168.13.13:8000/xxx/xxx/datapaaapi/planwork/api/xxx/xxx/inputRet")
.post(requestBody).addHeader("X-APP-ID", "xxxx").addHeader("X-APP-KEY", "bbbb").build();
try {
// 4.执行
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String responseBody = response.body().string();
// TODO:业务逻辑
log.info("解析后的 responseBo 对象是:{}", responseBo);
}
} catch (Exception e) {
log.error("推送xxx系统异常:{}", e);
}
return responseBo;
}
}
解决方案:
1,使用自签名证书或服务器证书
如果你不想忽略 SSL 验证,也可以考虑将服务器的证书或 CA 证书添加到 Java 的 truststore 中。这样,Java 就会信任该证书,不会抛出 SSLPeerUnverifiedException 错误。
2,使用 OkHttpClient 忽略 SSL 证书验证
package com.xxx.xx.xx.utils;
import com.alibaba.fastjson.JSON;
import com.xx.xx.xx.entity.bo.MajorBo;
import com.xx.xx.xx.entity.bo.xxx;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.util.CollectionUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
/**
* @author laoxu
*/
@Slf4j
public class PushInspectionStatisticsUtils {
public static PushInventoryResponseBo pushTaskInventoryFormWorkPlan(MajorBo majorBo) {
PushInventoryResponseBo responseBo = new PushInventoryResponseBo ();
// 1.创建okhttpClient
OkHttpClient client = createInsecureOkHttpClient();
// 2.构建请求头
MediaType mediaType = MediaType.parse("application/json;charset=UTF-8");
String jsonBody = JSON.toJSONString(majorBo);
RequestBody requestBody = RequestBody.create(jsonBody, mediaType);
// 3.封装请求头
Request request = new Request.Builder().url("http://192.168.13.13:8000/xxx/xxx/datapaaapi/planwork/api/xxx/xxx/inputRet")
.post(requestBody).addHeader("X-APP-ID", "xxxx").addHeader("X-APP-KEY", "bbbb").build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String responseBody = response.body().string();
// TODO:相关业务逻辑
log.info("解析后的 responseBo 对象是:{}", responseBo);
}
} catch (Exception e) {
log.error("推送xxx系统异常:{}", e);
}
return responseBo;
}
// 创建一个忽略 SSL 验证的 OkHttpClient
private static OkHttpClient createInsecureOkHttpClient() {
try {
// 创建一个不验证证书的 TrustManager
TrustManager[] trustAllCertificates = new TrustManager[]{
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// return null;
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// 允许所有客户端证书
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType){
// 允许所有客户端证书
}
}
};
// 安装不验证证书的 TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCertificates, new java.security.SecureRandom());
// 创建一个忽略主机名验证的 OkHttpClient
return new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCertificates[0])
// 关闭主机名验证
.hostnameVerifier((hostname, session) -> true)
.build();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new RuntimeException("Failed to create a secure OkHttpClient", e);
}
}
}
喜欢我的文章记得点个在看,或者点赞,持续更新中ing…