全部產品
Search
文件中心

Certificate Management Service:Java用戶端訪問HTTPS失敗:unable to find valid certification path to requested target

更新時間:Nov 26, 2025

本文檔深入剖析了Java用戶端因伺服器未提供完整憑證鏈結而導致“unable to find valid certification path”的HTTPS訪問失敗問題,並提供使用openssl排查及在服務端配置完整憑證鏈結的實用解決方案。

問題現象

Java應用程式通過HTTPS訪問服務端點時,串連失敗並拋出javax.net.ssl.SSLHandshakeException異常,核心錯誤資訊如下:

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

該問題通常伴隨以下現象:

  • 瀏覽器訪問正常:使用主流瀏覽器(如Chrome、Firefox)訪問同一HTTPS地址,串連成功且顯示安全鎖標誌。

  • 部分用戶端失敗:Java應用程式、curlwget等非瀏覽器用戶端訪問時,均報告TLS握手失敗或認證驗證錯誤。

問題原因

SSL/TLS協議依賴一個從伺服器憑證到用戶端信任的根憑證的完整“信任鏈結”。此錯誤的根本原因是Java用戶端無法構建出這條完整的信任鏈結。

  • 原因一:伺服器未提供完整的憑證鏈結

    伺服器在TLS握手時,僅發送了伺服器憑證(網域名稱認證),但遺漏了必要的中間認證。大多數非瀏覽器用戶端(包括Java)預設不具備從網路自動下載缺失認證的能力,導致驗證失敗。而現代瀏覽器具備AIA(Authority Information Access) chasing功能,可自動下載缺失的中間認證以補全憑證鏈結,因此訪問正常。

  • 原因二:用戶端JDK信任庫過舊

    伺服器已正確配置並發送了完整憑證鏈結,但憑證鏈結的根憑證(或交叉簽名的根憑證)未被用戶端的JDK信任。通常發生在用戶端JDK版本過舊,其內建的信任庫($JAVA_HOME/jre/lib/security/cacerts)不包含新版根憑證(例如,DigiCert從G1根切換到G2根後,舊版JDK可能不信任G2根),詳情可參考關於DigiCert根替換公告

解決方案

排查此問題應遵循“先服務端,後用戶端”的順序。首先使用openssl命令診斷伺服器配置,確認憑證鏈結是否完整。若服務端配置無誤,再檢查用戶端環境。

步驟一:檢查伺服器憑證鏈配置

此步驟用於確認伺服器在TLS握手時是否發送了完整的憑證鏈結。

  1. 在任意一台已安裝OpenSSL的裝置上,執行以下命令。將your.domain.com:443替換為實際的服務端點地址和連接埠。

    # 串連伺服器並顯示其提供的憑證鏈結
    openssl s_client -connect your.domain.com:443 -showcerts
  2. 分析命令輸出中的Certificate chain部分和Verify return code

    • 問題情境(憑證鏈結不完整)

      輸出中僅有一個以depth=0開頭的認證,且末尾的驗證返回碼非0,通常為Verify return code: 20 (unable to get local issuer certificate)。這明確表示伺服器未提供中間認證。

      Certificate chain
       0 s:/CN=your.domain.com
         i:/C=US/O=DigiCert Inc/CN=DigiCert TLS RSA SHA256 2020 CA1
      ---
      Server certificate
      -----BEGIN CERTIFICATE-----
      (伺服器憑證內容)
      -----END CERTIFICATE-----
      ...
      Verify return code: 20 (unable to get local issuer certificate)
    • 正常情境(憑證鏈結完整)

      輸出中包含多個認證,形成從depth=0(伺服器憑證)到depth=1(中間認證)的有序鏈條。驗證返回碼為Verify return code: 0 (ok)

      Certificate chain
       0 s:/CN=your.domain.com
         i:/C=US/O=DigiCert Inc/CN=DigiCert TLS RSA SHA256 2020 CA1
       1 s:/C=US/O=DigiCert Inc/CN=DigiCert TLS RSA SHA256 2020 CA1
         i:/C=US/O=DigiCert Inc/CN=DigiCert Global Root CA
      ---
      ...
      Verify return code: 0 (ok)

步驟二:修複問題

根據步驟一的診斷結果,執行對應的修複操作。

情境一:修複不完整的伺服器憑證鏈

openssl診斷結果為憑證鏈結不完整,需在伺服器端(如Nginx、Apache、Tomcat、Server Load Balancer等)重新設定認證。

  1. 從憑證授權單位(CA)擷取包含伺服器憑證和所有中間認證的認證包檔案。該檔案通常命名為fullchain.pemchain.pem

  2. 確保認證包檔案內容遵循以下順序:伺服器憑證在前,中間認證在後。

    -----BEGIN CERTIFICATE-----
    (您的伺服器憑證內容)
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    (中間認證1的內容)
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    (中間認證2的內容,如果存在)
    -----END CERTIFICATE-----
  3. 參考您的Web伺服器或網關的官方文檔,將其SSL認證配置指向此完整的認證包檔案,然後重啟服務使配置生效。

情境二:處理用戶端JDK信任庫問題

openssl診斷結果顯示伺服器憑證鏈完整,但Java用戶端依然報錯,則問題很可能源於用戶端JDK版本過舊。

  • 推薦方案:升級JDK 將用戶端應用的JDK升級至最新的長期支援(LTS)版本(如JDK 8、11、17的最新更新版)。新版JDK包含了最新的根憑證庫,能解決因CA根憑證更替導致的問題,同時也能獲得重要的安全修複和效能提升。

  • 臨時方案:手動匯入根憑證至信任庫 若無法立即升級JDK,可手動將缺失的根憑證匯入到當前JDK的cacerts信任庫中。

    1. 擷取缺失的根憑證檔案,可參考下載根憑證

    2. 執行以下keytool命令將其匯入。預設密碼為changeit

      # 將<path-to-root-ca.crt>替換為根憑證檔案路徑
      # 將$JAVA_HOME替換為您的Java安裝目錄
      keytool -import -alias <give-a-unique-alias> -keystore $JAVA_HOME/jre/lib/security/cacerts -file <path-to-root-ca.crt> -storepass changeit

後續建議

  • 配置最佳化:將認證更新流程標準化。在每次更新認證時,都必須驗證並部署完整的憑證鏈結檔案,而非僅部署網域名稱認證檔案。

  • 監控警示購買並開啟公網網域名稱監控,定期探測HTTPS服務的認證狀態,避免認證到期導致網站不可用。