解决出现javax.net.ssl.SSLHandshakeException: PKIX path building failed 或 sun.security.validator.ValidatorException: PKIX path building failed的问题
当我们从网络上根据url下载文件的时候可能会出现一下异常
错误信息:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
问题原因:
在Java8及高版本以上的版本在源应用程序不信任目标应用程序的证书,因为在源应用程序的JVM信任库中找不到该证书或证书链。也就是目标站点启用了HTTPS 而缺少安全证书时出现的异常
常见的解决方法有三种:
1. 手动生成证书;
2. 忽略证书验证。(建议使用)
3. 在JDK安装目录中删除
三种方式的实现:
1、手动导入安全证书
手动生成证书方法参考大佬博客:手动生成证书方法
2、忽略证书验证(建议使用)
public class Base64Util {
public static String getBase64FromUrl(String fileUrl) {
InputStream inputStream = null;
byte[] data = null;
ByteArrayOutputStream swapStream = null;
HttpsURLConnection conn = null;
try {
URL url = new URL(fileUrl);
//判断当前文件url是否是https
if (fileUrl.contains("https:")){
//是https
//绕过证书
SSLContext context = createIgnoreVerifySSL();
conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(context.getSocketFactory());
inputStream = conn.getInputStream();
}else {
//当前链接是http
inputStream = url.openConnection().getInputStream();
}
swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = inputStream.read(buff, 0, 100)) > 0) {
swapStream.write(buff, 0, rc);
}
data = swapStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(swapStream);
}
return new String(Base64.encodeBase64(data));
}
//绕过SSL、TLS证书
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("TLS");
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[]{trustManager}, null);
return sc;
}
}
3、删除JDK安装目录下jre/lib/security的java.security
文件的SSLv3, TLSv1, TLSv1.1
,(不建议使用,本地环境和生产环境不一样)