Java 下载第三方文件:解决 SSLHandshakeException 错误

在使用 Java 下载第三方文件时,有时会遇到 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed 错误,这通常是由于缺少证书导致的。以下介绍几种常见的解决方法:

1. 导入第三方网站的 SSL 证书到 Java 信任库

可以使用 keytool 命令将证书导入到 Java 的信任库中:

keytool -import -alias thirdCert -keystore cacerts -file thirdCert.crt

其中:

  • thirdCert 是证书别名,可以自定义。
  • cacerts 是 Java 信任库文件,通常位于 <JDK_HOME>/jre/lib/security/cacerts 目录下。
  • thirdCert.crt 是第三方网站的 SSL 证书文件。

2. 创建自定义 TrustManager

如果使用的是自签名证书,可以通过创建自定义的 TrustManager 来信任该证书。示例代码如下:

TrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
        }
        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
        }
    }
};

SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

// 使用该信任管理器发送请求
URL url = new URL(thirdUrl);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(sc.getSocketFactory());

注意

  • 以上解决方法可能存在安全风险,请根据具体情况选择合适的方法。
  • 导入证书或创建自定义 TrustManager 可能会导致应用程序不安全,请谨慎使用。

代码示例

以下代码示例展示了如何使用自定义 TrustManager 下载第三方文件:

public RespBean downloadThirdFile(HttpServletResponse response) throws UnsupportedEncodingException {
    String thirdUrl = 'https://dppt.tianjin.chinatax.gov.cn:8443/kpfw/fpjfzz/v1/exportDzfpwjEwmWjgs=PDF&Jym=728E&Fphm=23122000000008542853&Kprq=20230905145917&Czsj=1693897158216';
    response.setContentType("application/x-msdownload");
    response.setHeader("Content-Disposition", "attachment;filename=" + new String((DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".pdf").getBytes(), "ISO-8859-1"));
    if (StrUtil.isBlank(thirdUrl)) {
        return new RespBean("success", "下载失败");
    }
    if (!thirdUrl.toLowerCase().contains("http")) {
        thirdUrl = "http://" + thirdUrl;
    }
    HttpURLConnection httpUrl = null;
    BufferedInputStream in = null;
    try {
        URL url = new URL(thirdUrl);
        // 创建自定义 TrustManager
        TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
        };
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setSSLSocketFactory(sc.getSocketFactory());
        // ...
    } catch (Exception e) {
        e.printStackTrace();
        return new RespBean("error", "下载文件失败");
    } finally {
        // ...
    }
    return new RespBean("success", "下载成功");
}

希望本文对你有所帮助。

Java 下载第三方文件:解决 SSLHandshakeException 错误

原文地址: https://www.cveoy.top/t/topic/qELS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录