解决 javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

运行环境 tomcat9.0+jdk11

我用tomcat1上的程序去访问本机的tomcat2上的程序报错:javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target。我的程序是这样的:

try { HttpClient client = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_2) .build(); java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder() .uri(URI.create(urlStr)) .timeout(Duration.ofSeconds(10)) // 设置超时时间,可根据实际情况调整 .GET() .build(); String jsonString = ""; try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(urlStr + "==" + jsonString); jsonString = response.body(); } catch (IOException | InterruptedException e) { e.printStackTrace(); }

 解决方案一:创建了一个自定义的TrustManager,它会信任所有的证书,在测试环境中可以快速解决证书验证问题,但在生产环境中会带来安全风险,因为它不进行真正的证书验证,容易受到中间人攻击

         这里的`storepass`是`cacerts`文件的默认密码`changeit`。
   - **方法二:配置自定义SSLContext(更灵活,适用于复杂场景)**
     - **创建自定义TrustManager(信任所有证书,仅用于测试,有安全风险)**:
       ```java
       import javax.net.ssl.SSLContext;
       import javax.net.ssl.TrustManager;
       import javax.net.ssl.X509TrustManager;
       import java.net.http.HttpClient;
       import java.security.NoSuchAlgorithmException;
       import java.security.cert.CertificateException;
       import java.security.cert.X509Certificate;
       //...
       try {
           TrustManager[] trustAllCerts = new TrustManager[]{
               new X509TrustManager() {
                   @Override
                   public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
                   @Override
                   public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
                   @Override
                   public X509Certificate[] getAcceptedIssuers() {
                       return null;
                   }
               }
           };
           SSLContext sslContext = SSLContext.getInstance("TLS");
           sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
           HttpClient client = HttpClient.newBuilder()
              .version(HttpClient.Version.HTTP_2)
              .sslContext(sslContext)
              .build();
           java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
              .uri(URI.create(urlStr))
              .timeout(java.time.Duration.ofSeconds(10))
              .GET()
              .build();
           String jsonString = "";
           try {
               HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
               System.out.println(urlStr + "==" + jsonString);
               jsonString = response.body();
           } catch (IOException | InterruptedException e) {
               e.printStackTrace();
           }
       } catch (NoSuchAlgorithmException | KeyManagementException e) {
           e.printStackTrace();
       }

 二:正确配置 TrustManager(使用服务器证书进行验证)

import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
//...
try {
    KeyStore keyStore = KeyStore.getInstance("JKS");
    FileInputStream fis = new FileInputStream("keystore.jks");
    keyStore.load(fis, "password".toCharArray());
    fis.close();
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustManagers, new java.security.SecureRandom());
    HttpClient client = HttpClient.newBuilder()
       .version(HttpClient.Version.HTTP_2)
       .sslContext(sslContext)
       .build();
    // 后续代码与之前的HttpRequest和HttpResponse处理相同
} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | KeyManagementException e) {
    e.printStackTrace();
}

 

posted @ 2024-12-16 20:10  锐洋智能  阅读(765)  评论(0)    收藏  举报