记录一次线上bug修改过程。
线上服务中有一个需要调用对接接口的业务,对接的接口是 https协议的,之前请求一直没有问题,最近对方反馈收不到我们的请求了,所以到线上看了下,发现了了一些错误日志:
javax.net.ssl.SSLException: Received fatal alert: protocol_version
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[na:1.7.0_45]
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) ~[na:1.7.0_45]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) ~[na:1.7.0_45]
...
查了相关资料,说是因为JDK的版本问题导致会使用不同的TLS协议。
我检查了下线上JDK的版本,是1.7版本,1.7版本的JDK默认是使用TLS协议。两种办法解决这个问题
调整了线上JDK的版本到1.8,1.8版本的JDK默认使用TLSv1.2 协议,调整后此问题就没有了。
当然还有一种办法,就是给在JDK1.7的环境下,主动设置使用TLS1.2 协议,不是使用默认的TLS协议。此方法还可以解决https正式验证问题。
CloseableHttpClient httpClient = HttpClients.custom().
setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
.setSSLSocketFactory(buildSslSocketFactoryForIgnoreCertificate())
.build();
private static SSLSocketFactory buildSslSocketFactoryForIgnoreCertificate() throws NoSuchAlgorithmException, KeyManagementException {
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
SSLContext sslcontext = SSLContext.getInstance("TLSv1.2");
sslcontext.init(null, new TrustManager[]{trustManager}, null);
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(sslcontext);
sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return sslSocketFactory;
}
之所以之前一直正常,后来请求失败。我感觉很大可能是对方的服务器限制了TLS协议的请求。
关于TLS协议和SSL的区别及介绍,可以看此文章:https://kb.cnblogs.com/page/197396/