1,作者遇见的是HttpClients请求,使用p12证书。windows请求正常,放到linux上就报javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)这个错误,原因是指示SSL/TLS握手过程中未能找到合适的协议版本或密码套件。这通常是因为服务器和客户端之间支持的加密协议或密码套件不匹配。
2,在linux上使用下面这条命令会列出所有支持的密码套件及其支持的协议版本,你可以从中查找是否有TLSv1相关的条目。
openssl ciphers -v | grep "TLSv1"
查询结果:
3,修改代码或者需要安装TLSv1版本。作者选择修改代码,修改代码如下:
public static String refund(WXRequestRefundEntity refund, String url, String SSLCERT_PATH, String SSLCERT_PASSWORD) throws Exception {
if (StringUtils.isBlank(refund.getKey())) {
throw new Exception("key不能为空");
}
String data = getXml(refund);
CloseableHttpClient httpclient = null;
CloseableHttpResponse response = null;
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File(SSLCERT_PATH));//P12
keyStore.load(instream, SSLCERT_PASSWORD.toCharArray());
instream.close();
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, SSLCERT_PASSWORD.toCharArray())
.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[]{"TLSv1.2"}, //把这里改成对应系统里面的版本即可
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
HttpPost httpost = new HttpPost(url);
httpost.addHeader("Connection", "keep-alive");
httpost.addHeader("Accept", "*/*");
httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httpost.addHeader("Host", "api.mch.weixin.qq.com");
httpost.addHeader("X-Requested-With", "XMLHttpRequest");
httpost.addHeader("Cache-Control", "max-age=0");
httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
httpost.setEntity(new StringEntity(data, "UTF-8"));
response = httpclient.execute(httpost);
return EntityUtils.toString(response.getEntity(), "UTF-8");
}finally {
if (httpclient != null){
httpclient.close();
}
if (response != null){
response.close();
}
}
}
请作者喝杯咖啡