首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java HTTPS 雙向認證實戰:InstallCert 獲取證書、配置 TrustStore、調用 WebService 完整流程

     編輯:Java 綜合教學

Java 調用 HTTPS WebService 全流程:從證書獲取到雙向認證配置

調用 HTTPS 服務時,若服務端證書非公信 CA 簽發(自簽名/內網 CA),JDK 默認 TrustStore 不信任,會拋出 PKIX path building failed。本文詳述 InstallCert 獲取證書、導入 TrustStore、代碼配置雙向認證的完整步驟。

1. 獲取服務端證書:InstallCert 工具類

源碼來自 Oracle 官方範例,核心邏輯:建立自定義 TrustManager 捕獲握手時的證書鏈,交互式選擇導入 jssecacerts。

public class InstallCert {
    public static void main(String[] args) throws Exception {
        // 解析 host:port、passphrase
        // 載入或創建 jssecacerts
        // 初始化 SSLContext + SavingTrustManager
        // 建立 SSLSocket 執行握手
        // 打印證書鏈信息(Subject、Issuer、SHA1、MD5)
        // 用戶選擇導入哪張證書,寫入 jssecacerts
    }
    // SavingTrustManager 內部類捕獲 server certificate chain
}

使用步驟:

  1. 新建 Java 專案,複製 InstallCert.java。
  2. Eclipse Run Configurations → Arguments → Program arguments: api.example.com:443 changeit(host:port + keystore 密碼)。
  3. Run,控制台報錯 SSLException 正常,輸入 1 回車選擇第一張證書。
  4. 專案根目錄生成 jssecacerts 文件。

2. 部署證書

推薦複製到 JDK 目錄:

cp jssecacerts $JAVA_HOME/jre/lib/security/   # Linux/Mac
copy jssecacerts %JAVA_HOME%\jre\lib\security\  # Windows

或項目內部路徑,啟動參數指定:-Djavax.net.ssl.trustStore=./jssecacerts。

3. 代碼配置 HTTPS 調用

3.1 靜態代碼塊設置 TrustStore(單向認證)

static {
    // 1. 域名驗證(生產環境請嚴格校驗 CN/SAN)
    HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> 
        "api.example.com".equals(hostname) || "10.0.0.5".equals(hostname)
    );

    // 2. 指定 TrustStore
    System.setProperty("javax.net.ssl.trustStore", "C:/Java/jdk1.8/jre/lib/security/jssecacerts");
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
}

3.2 雙向認證(雙向 SSL / Mutual TLS)

若服務端要求客戶端證書:

static {
    // TrustStore(信任服務端)
    System.setProperty("javax.net.ssl.trustStore", "/path/jssecacerts");
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

    // KeyStore(提供客戶端證書)
    System.setProperty("javax.net.ssl.keyStore", "/path/client.p12"); // PKCS12 格式
    System.setProperty("javax.net.ssl.keyStorePassword", "keystorePwd");
    System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
}

或程序化構建 SSLContext(推薦,線程安全、可熱更新):

SSLContext ctx = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("client.p12"), "keystorePwd".toCharArray());
kmf.init(ks, "keypwd".toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ts = KeyStore.getInstance("JKS");
ts.load(new FileInputStream("jssecacerts"), "changeit".toCharArray());
tmf.init(ts);

ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

4. 常見報錯排查清單

5. 生產環境最佳實踐

  1. 不要硬編碼路徑:配置中心管理 ssl.trustStore.path、ssl.keyStore.path。
  2. 證書輪換自動化:監聽證書過期時間,CI/CD 流水線自動更新 TrustStore/KeyStore,滾動重啟服務。
  3. 啟用 OCSP Stapling / CRL 檢查:System.setProperty("com.sun.net.ssl.checkRevocation", "true")。
  4. 容器化部署:證書掛載為 Secret/ConfigMap,啟動腳本注入系統屬性。
  5. 監控指標:SSL 握手耗時、失敗率、證書剩餘天數,接入 Prometheus/Grafana 告警。

掌握上述流程,即可從容應對內網自簽名 CA、雙向認證、證書輪換等各類 HTTPS 集成場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤原因解決
PKIX path building failedTrustStore 缺少服務端根證書重新運行 InstallCert 導入正確證書
hostname in certificate didn't match證書 CN/SAN 不匹配請求域名/IP修正 HostnameVerifier 或獲取正確域名證書
Received fatal alert: handshake_failure協議/加密套件不匹配、雙向認證缺客戶端證書啟用 `-Djavax.net.debug=ssl:handshake` 分析 ClientHello/ServerHello
keystore password was incorrecttrustStorePassword/keyStorePassword 錯誤核對 InstallCert 運行時輸入的 passphrase