HttpURLConnection 跳过ssl验证

本文介绍了解决使用HttpURLConnection下载HTTPS资源时遇到的证书验证失败问题,通过自定义证书信任管理和主机名验证,实现对所有主机的信任,避免了因证书问题导致的下载失败。

使用HttpURLConnection链接https资源时验证不通过报错如下

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
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1964)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:162)
	at com.lovnx.note.rabbitmq.listener.ThreeCallBackListener.downLoadFromUrl(ThreeCallBackListener.java:338)
	at com.lovnx.note.rabbitmq.listener.ThreeCallBackListener.main(ThreeCallBackListener.java:468)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
	at sun.security.validator.Validator.validate(Validator.java:262)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
	... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
	... 18 more

Process finished with exit code 0

 

解决

public static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        boolean useHttps = urlStr.startsWith("https");
        if (useHttps) {
            HttpsURLConnection https = (HttpsURLConnection) conn;
            trustAllHosts(https);
            https.setHostnameVerifier(DO_NOT_VERIFY);
        }
        //设置超时间为3秒
        conn.setConnectTimeout(3 * 1000);
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        conn.setDoInput(true);
        conn.connect();
        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组

        byte[] getData = readInputStream(inputStream);
        //文件保存位置

        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }

        File file = new File(saveDir + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);

        if (fos != null) {
            fos.close();
        }

        if (inputStream != null) {
            inputStream.close();
        }
        status = true;

        log.info("pdfUrl文件下载,url=[{}],保存地址=[{}],文件名=[{}]", url, savePath, fileName);
    }
/**
     * 覆盖java默认的证书验证
     */
    private static final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
    }};

    /**
     * 设置不验证主机
     */
    private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    /**
     * 信任所有
     * @param connection
     * @return
     */
    private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) {
        SSLSocketFactory oldFactory = connection.getSSLSocketFactory();
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            SSLSocketFactory newFactory = sc.getSocketFactory();
            connection.setSSLSocketFactory(newFactory);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return oldFactory;
    }

测试

    public static void main(String[] args) {
        try {
            downLoadFromUrl("https://文件路径",
                    "百度.pdf", "temp/");
        } catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }
    }

到此结束了,修改要获取文件的https路径即可下载

参考链接: https://www.jianshu.com/p/a928b6c34f06

在SAP开发中,如果你需要调用HTTPS接口并想要跳过SSL验证以进行调试,通常这不应该被视为最佳实践,因为这样做可能会暴露你的应用对非安全连接的依赖,增加潜在的安全风险。但在某些特定环境中,比如测试阶段,可以使用SAP Java SDK的`HttpsURLConnection`或者第三方库如Apache HttpClient的`CloseableHttpClient`,配合`SSLSocketFactory`来临时绕过SSL校验。 下面是一个使用`HttpsURLConnection`示例(仅适用于Java SE): ```java import javax.net.ssl.HttpsURLConnection; import java.io.InputStream; // ...其他 imports... try { // 创建URL实例 URL url = new URL("https://example.com/api"); // 创建无验证HttpURLConnection实例 HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setSSLSocketFactory(new AllowAllSSLSocketFactory()); // 设置忽略证书错误 connection.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); // 接下来你可以设置请求方法、获取响应等... connection.setRequestMethod("GET"); // 获取输入流处理响应 InputStream inputStream = connection.getInputStream(); // ...处理输入流内容 } catch (Exception e) { // 错误处理 e.printStackTrace(); } class AllowAllSSLSocketFactory extends SSLSocketFactory { public Socket createSocket() throws IOException { return new Socket(); } public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return s; } public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return new Socket(host, port); } } ``` 然而,记住这只是为了临时解决开发环境的问题,在生产环境中一定要启用有效的SSL/TLS认证。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值