解决出现javax.net.ssl.SSLHandshakeException: PKIX path building failed 或 sun.security.validator.ValidatorException: PKIX path building failed的问题
From: https://www.cnblogs.com/luoxiao1104/p/16671501.html
当我们从网络上根据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
,(不建议使用,本地环境和生产环境不一样)
------------------------ 以下为个人整理的一个文件下载的工具类,仅供参考 ----------------------
开发环境:Windows 10 + JDK21
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | package com.ruoyi.common.util; import cn.hutool.core.io.FileUtil; import lombok.Data; import lombok.extern.slf4j.Slf4j; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; @Data @Slf4j public class FileDownloader { private String saveDir; // 服务器上文件存储目录 public FileDownloader(String saveDir) { this .saveDir = saveDir; } private String getSavePath(String fileName) { return saveDir + "/" + fileName; } public int download(String remoteFileUrl) { InputStream is; try { // 构造URL URL url = new URL(remoteFileUrl); // 打开连接 URLConnection con = url.openConnection(); // 设置请求头 con.addRequestProperty( "User-Agent" , "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)" ); // 设置请求超时为5s con.setConnectTimeout( 5 * 1000 ); if (remoteFileUrl.startsWith( "https:" )) { SSLContext context = createIgnoreVerifySSL(); con = url.openConnection(); ((HttpsURLConnection) con).setSSLSocketFactory(context.getSocketFactory()); } is = con.getInputStream(); // 1K的数据缓冲 byte [] bs = new byte [ 1024 ]; // 读取到的数据长度 int len; // 输出的文件流 String name = FileUtil.getName(remoteFileUrl); var savepath = getSavePath(name); var dir = new File(saveDir); if (!dir.exists()) { dir.mkdirs(); } OutputStream os = new FileOutputStream(savepath); // 开始读取 while ((len = is.read(bs)) != - 1 ) { os.write(bs, 0 , len); } // 完毕,关闭所有链接 os.close(); is.close(); return 1 ; } catch (MalformedURLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { System.out.println( "下载文件路径不存在:" + remoteFileUrl); } catch (IOException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (KeyManagementException e) { throw new RuntimeException(e); } return 0 ; } /** * 参考: https://www.cnblogs.com/luoxiao1104/p/16671501.html * 在Java8及高版本以上的版本在源应用程序不信任目标应用程序的证书,因为在源应用程序的JVM信任库中找不到该证书或证书链。也就是目标站点启用了HTTPS 而缺少安全证书时出现的异常 * * @return * @throws NoSuchAlgorithmException * @throws KeyManagementException */ 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; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)