概述
日常上传、下载文件时可能有不需要验证证书的场景,比如证书过期、不正确之类的也可以正常的上传下载文件。
Java中使用https协议时,是通过X.509证书进行校验的。
首先我们先了解下什么是X.509证书。
什么是X.509证书
X.509是公钥基础设施(PKI:Public Key Infrastructure)的标准格式,其实就是一种证书的标准格式,规定证书是什么样的。
X.509证书就是基于国际电线联盟(ITU)制定的X.509标准的数字证书。
X.509证书主要用于识别互联网通信和计算机网络中的身份,保护数据传输安全。X.509证书无处不在,比如我们每天使用的网站、移动应用程序、电子文档以及连接的设备等都有它的身影。
X.509证书的结构优势在于它是由公钥和私钥组成的密钥对而构建的。公钥和私钥能够用于加密和解密信息,验证发送者的身份和确保信息本身的安全性。基于X.509的PKI最常见的用例是使用SSL证书让网站与用户之间实现HTTPS安全浏览。X.509协议统一也使用于应用程序安全的代码签名、数字签名和其他重要的互联网协议。
证书校验引发的问题
javax.net.ssl.SSLException: hostname in certificate didn’t match
含义就是说现在程序运行的域名,与请求的证书不一致,不匹配导致的。那么解决方案必定是把证书忽略了,也就是不验证证书的情况下请求上游信息了。
java原生客户端忽略证书
public static String sendSSLPost(String url, String param) {
StringBuilder result = new StringBuilder();
String urlNameString = url + "?" + param;
try {
log.info("sendSSLPost - {}", urlNameString);
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] {
new TrustAnyTrustManager()
}, new java.security.SecureRandom());
URL console = new URL(urlNameString);
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
conn.connect();
InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String ret = "";
while ((ret = br.readLine()) != null) {
if (ret != null && !ret.trim().equals("")) {
result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
}
}
log.info("recv - {}", result);
conn.disconnect();
br.close();
} catch (ConnectException e) {
log.error("sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
} catch (SocketTimeoutException e) {
log.error("sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
} catch (IOException e) {
log.error("sendSSLPost IOException, url=" + url + ",param=" + param, e);
} catch (Exception e) {
log.error("sendSSLPost Exception, url=" + url + ",param=" + param, e);
}
return result.toString();
}
// 信任所有证书(就是忽略证书校验)
private static class TrustAnyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
// 信任任何主键名(不校验主机名和证书的关系)
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
org.apache.httpcomponents httpclient客户端忽略证书方法
参考
什么是X.509证书?X.509证书工作原理及应用?
java忽略证书验证(兼容http,https)进行get/post请求–使用(org.apache.httpcomponents httpclient客户端)