Received fatal alert:handshake_failure 异常解决方法
目录1.背景2. 报错信息3.问题分析4. 解决方法1.背景PCI认证,要求安全传输层协议由之前的TLS v1.0、TLS v1.1升级到TLS v1.2。2. 报错信息java.lang.Exception: 接口调用失败:at com.huateng.szairpay.common.utils.HTTPSInvoke.sendHttpsRequest...
文章共725字 · 阅读需要大约3分钟
一键AI生成摘要,助你高效阅读
问答
·
目录
1. 背景
PCI认证,要求安全传输层协议由之前的TLS v1.0、TLS v1.1升级到TLS v1.2。
2. 报错信息
java.lang.Exception: 接口调用失败:
at com.huateng.szairpay.common.utils.HTTPSInvoke.sendHttpsRequestByPost(HTTPSInvoke.java:97)
at com.huateng.szairpay.common.utils.HTTPSInvoke.main(HTTPSInvoke.java:193)
Caused by: java.security.NoSuchAlgorithmException: TLSv SSLContext not available
at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
at javax.net.ssl.SSLContext.getInstance(SSLContext.java:156)
at com.huateng.szairpay.common.utils.HTTPSInvoke.sendHttpsRequestByPost(HTTPSInvoke.java:70)
... 1 more
3. 问题分析
经查阅资料,发现jdk1.7是默认采用TLSv1.0版本。如图所示:
4. 解决方法
- 创建
SSLContext
实例,明确指定使用TLS
协议进行处理:
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
- 参考代码
public class HTTPSInvoke {
private static final Log log = LogFactory.getLog(HTTPSInvoke.class);
public static String sendHttpsRequestByPost(String url, Map<String, String> params) throws Exception {
String responseContent = null;
HttpClient httpClient = new DefaultHttpClient();
X509TrustManager xtm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return false;
}
public void verify(String arg0, SSLSocket arg1) throws IOException {
}
public void verify(String arg0, X509Certificate arg1) throws SSLException {
}
public void verify(String arg0, String[] arg1, String[] arg2) throws SSLException {
}
};
try {
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
ctx.init(null, new TrustManager[]{xtm}, null);
SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
socketFactory.setHostnameVerifier(hostnameVerifier);
httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", socketFactory, 443));
log.info("调用接口:" + url);
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : params.entrySet()) {
formParams.add(new BasicNameValuePair((String) entry.getKey(), (String) entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
responseContent = EntityUtils.toString(entity, "UTF-8");
}
} catch (KeyManagementException e) {
throw new Exception("接口调用失败:", e);
} catch (NoSuchAlgorithmException e) {
throw new Exception("接口调用失败:", e);
} catch (UnsupportedEncodingException e) {
throw new Exception("接口调用失败:", e);
} catch (ClientProtocolException e) {
throw new Exception("接口调用异常:", e);
} catch (ParseException e) {
throw new Exception("接口调用失败:", e);
} catch (IOException e) {
throw new Exception("接口调用失败:", e);
} finally {
httpClient.getConnectionManager().shutdown();
}
return responseContent;
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)