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

HttpClient 繞過 SSL 憑證驗證:信任所有憑證的完整實現方案

     編輯:Java 綜合教學

問題背景

使用 Apache HttpClient 訪問 HTTPS 資源時,若目標伺服器使用自簽名憑證或憑證鏈不完整,會拋出 SSLHandshakeException: PKIX path building failed。開發/測試環境常需繞過驗證。

核心實現:信任所有憑證與主機名

import javax.net.ssl.*;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import java.io.*;
import java.security.SecureRandom;

public class HttpsTrustAllExample {
    public static void main(String[] args) throws Exception {
        // 1. 建立信任所有憑證的 TrustManager
        TrustManager[] trustAll = new TrustManager[]{
            new X509TrustManager() {
                public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {}
                public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {}
                public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[0]; }
            }
        };

        // 2. 初始化 SSLContext
        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(null, trustAll, new SecureRandom());

        // 3. 允許所有主機名
        HostnameVerifier allHostsValid = (hostname, session) -> true;

        // 4. 建立 HttpClient
        SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(ctx, allHostsValid);
        var httpClient = HttpClients.custom().setSSLSocketFactory(sslFactory).build();

        // 5. 執行請求並下載圖片示例
        String url = "https://pic2.zhimg.com/6f7c6805962dc58cc21d4df748f18125_xl.jpg";
        HttpGet get = new HttpGet(url);
        var response = httpClient.execute(get);
        try (InputStream in = response.getEntity().getContent();
             OutputStream out = new FileOutputStream("httpstest.jpg")) {
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) != -1) out.write(buf, 0, len);
        }
        System.out.println("下載完成");
    }
}

關鍵點解析

  • X509TrustManager:空實現三個方法即信任所有伺服器/客戶端憑證。
  • HostnameVerifier:返回 true 忽略主機名驗證(防止 CN 不匹配報錯)。
  • SSLContext.init():傳入自定義 TrustManager 與 SecureRandom。

⚠️ 生產環境警示

嚴禁在生產環境使用此方案! 這會導致中間人攻擊風險。正確做法:

  1. 將目標伺服器憑證匯入 JVM 信任庫(keytool -import)。
  2. 或建立專屬 TrustStore,僅信任特定 CA。
  3. 生產環境務必啟用完整憑證鏈與主機名驗證。

適用場景

  • 本地開發對接測試環境自簽名憑證服務。
  • 爬蟲/測試腳本臨時繞過驗證(需評估風險)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved