首页 > 解决方案 > 在验证多个 URL 时无法在 java 中找到请求目标的有效证书路径

问题描述

我正在尝试对 java 程序中的多个 URL 执行 ssl 证书身份验证,我已将 URL 存储在 arrayList 中并将它们作为参数传递给执行证书身份验证并提供来自服务器的响应的方法。

在手动输入和通过变量的情况下,上述方法适用于单个 URL。但是,通过 arrayList 传递这些 URL,从第二个 URL 到第 n 个 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
    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.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347)
    at com.redeem.GetREsponse.getResponse(GetREsponse.java:108)
    at com.redeem.Check1.main(Check1.java:20)
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)
    ... 15 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)
    ... 21 more
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**

如何解决这个问题?

我遵循不同方法的代码片段

public class Check1 {
static ArrayList<String> arrayList;
public static void main(String[] args) {
    arrayList = new ArrayList();
    //GetREsponse get = new GetREsponse();
    arrayList.add("URL1");
    arrayList.add("URL2");
    arrayList.add("URL3");


    for(int i = 0; i < arrayList.size(); i++)
    {
        //GetREsponse get = new GetREsponse();
        GetREsponse.getResponse(arrayList.get(i));

    /*  Thread1 t = new Thread1(i);
        t.start(); // try to check the status by providing delay
        try {       
            t.sleep(10000); 
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //continue;
        */
    }   
}

/*public static class Thread1 extends Thread
{
    int i1;
    public Thread1(int i)
    {
        i1 = i;
    }
    public void run()
    {
        //GetREsponse get = new GetREsponse();
        //get.getResponse(arrayList.get(i1));
        GetREsponse.getResponse(arrayList.get(i1));
    }
}

}*/


public class GetREsponse {
    static SSLContext sslcontext;
    static String Result;
    static StringBuilder sb = new StringBuilder();


    static void getResponse(String url)
    {
        System.out.println(url+"~swa");
        try {

            sslcontext = SSLContexts.custom()
                    .loadTrustMaterial(new File("C:/ssl/1.jks"),
                            "secret".toCharArray())
                    .loadKeyMaterial(new File("C:/ssl/certificate.p12"),
                            "secret".toCharArray(),
                            "secret".toCharArray())
                    .build();

            System.out.println("success");
        } catch (KeyManagementException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (KeyStoreException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (CertificateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                new String[] { "TLSv1" },
                null,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());

        // Directly configure HTTP authentication
        System.setProperty("javax.net.ssl.keyStore", "C:/ssl/1.jks");
      System.setProperty("https.protocols", "TLSv1");
      System.setProperty("javax.net.ssl.keyStorePassword", "password");
        String username = "Username";
        String password = "loginpassword";
        String authString = username + ":" + password;
        String authHeader= null;
        try {
            authHeader = "Basic " + Base64.getEncoder().encodeToString(authString.getBytes("UTF-8"));
            System.out.println("success");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)`enter code here`
                .build();
        System.out.println("success");


        try {

            URL url1 = new URL(url);

            HttpsURLConnection urlConn = (HttpsURLConnection) url1.openConnection();
            urlConn.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
            System.out.println("1");
            urlConn.setDoOutput(true);
            urlConn.setRequestMethod("GET");

            urlConn.setRequestProperty("Authorization", authHeader);
            urlConn.setRequestProperty("Content-Type", "application/json");
            urlConn.setRequestProperty("Accept", "application/json");

            System.out.println("2");

           int response = urlConn.getResponseCode();
            System.out.println("3");

            System.out.println(response+"");

            InputStream inputStream = urlConn.getInputStream(); 
            InputStreamReader i_reader = new InputStreamReader(inputStream); 
            BufferedReader b_reader = new BufferedReader(i_reader);
            String str = b_reader.readLine();
            while(str != null)
            {
                sb.append(str);
                str = b_reader.readLine();
            }
            Result = sb.toString();
            System.out.println(sb.toString());            
            } 
            catch(Exception e)
            {
                e.printStackTrace();
                System.out.println(e.toString());
            } finally {
            try {
                httpclient.close();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println(e.toString());
            }
        }
    }
}

标签: javassl-certificate

解决方案


推荐阅读