国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

關于java訪問https資源時,忽略證書信任問題

songjz / 2530人閱讀

摘要:程序在訪問資源時,出現報錯這本質上,是在訪問資源時的證書信任問題。因此,如果用訪問資源,發現證書不可信任,則會報文章開頭說到的錯誤。

java程序在訪問https資源時,出現報錯
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
這本質上,是java在訪問https資源時的證書信任問題。
如何解決這個問題呢?
解決這個問題前,要了解
1)https通信過程
客戶端在使用HTTPS方式與Web服務器通信時有以下幾個步驟,如圖所示。
(1)客戶使用https的URL訪問Web服務器,要求與Web服務器建立SSL連接。
(2)Web服務器收到客戶端請求后,會將網站的證書信息(證書中包含公鑰)傳送一份給客戶端。
(3)客戶端的瀏覽器與Web服務器開始協商SSL連接的安全等級,也就是信息加密的等級。
(4)客戶端的瀏覽器根據雙方同意的安全等級,建立會話密鑰,然后利用網站的公鑰將會話密鑰加密,并傳送給網站。
(5)Web服務器利用自己的私鑰解密出會話密鑰。
(6)Web服務器利用會話密鑰加密與客戶端之間的通信。


2)java程序的證書信任規則
如上文所述,客戶端會從服務端拿到證書信息。調用端(客戶端)會有一個證書信任列表,拿到證書信息后,會判斷該證書是否可信任。
如果是用瀏覽器訪問https資源,發現證書不可信任,一般會彈框告訴用戶,對方的證書不可信任,是否繼續之類。
Java虛擬機并不直接使用操作系統的keyring,而是有自己的security manager。與操作系統類似,jdk的security manager默認有一堆的根證書信任。如果你的https站點證書是花錢申請的,被這些根證書所信任,那使用java來訪問此https站點會非常方便。因此,如果用java訪問https資源,發現證書不可信任,則會報文章開頭說到的錯誤。

解決問題的方法
1)將證書導入到jdk的信任證書中(理論上應該可行,未驗證)
2)在客戶端(調用端)添加邏輯,忽略證書信任問題
第一種方法,需要在每臺運行該java程序的機器上,都做導入操作,不方便部署,因此,采用第二種方法。下面貼下該方法對應的代碼。
驗證可行的代碼
1)先實現驗證方法

HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            System.out.println("Warning: URL Host: " + urlHostName + " vs. "
                               + session.getPeerHost());
            return true;
        }
    };
 
 private static void trustAllHttpsCertificates() throws Exception {
 javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
 javax.net.ssl.TrustManager tm = new miTM();
 trustAllCerts[0] = tm;
 javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
 .getInstance("SSL");
 sc.init(null, trustAllCerts, null);
 javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
 .getSocketFactory());
 }
 
 static class miTM implements javax.net.ssl.TrustManager,
 javax.net.ssl.X509TrustManager {
 public java.security.cert.X509Certificate[] getAcceptedIssuers() {
 return null;
 }
 
 public boolean isServerTrusted(
 java.security.cert.X509Certificate[] certs) {
 return true;
 }
 
 public boolean isClientTrusted(
 java.security.cert.X509Certificate[] certs) {
 return true;
 }
 
 public void checkServerTrusted(
 java.security.cert.X509Certificate[] certs, String authType)
 throws java.security.cert.CertificateException {
 return;
 }
 
 public void checkClientTrusted(
 java.security.cert.X509Certificate[] certs, String authType)
 throws java.security.cert.CertificateException {
 return;
 }
}

2)在訪問https資源前,調用

trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);

以下是一個具體的例子:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import org.apache.log4j.Logger;
import org.htmlparser.util.ParserException;

import com.xwtech.parser.GetRequestHtmlParser;
import com.xwtech.pojo.ExtendCandidate;
/*
 * GET請求類
 */
public class GetRequest {
    private String url = "https://b2b.10086.cn/b2b/main/viewNoticeContent.html?noticeBean.id=";
    private Logger logger;
    public GetRequest() {
        logger = Logger.getLogger(GetRequest.class);
    }
    private static void trustAllHttpsCertificates() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }
    public void getData(String id) {
        this.url = url + id;
        BufferedReader in = null;
        HttpURLConnection conn = null;
        String result = "";
        try {
        //該部分必須在獲取connection前調用
            trustAllHttpsCertificates();
            HostnameVerifier hv = new HostnameVerifier() {
                public boolean verify(String urlHostName, SSLSession session) {
                    logger.info("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
                    return true;
                }
            };
            HttpsURLConnection.setDefaultHostnameVerifier(hv);
            conn = (HttpURLConnection)new URL(url).openConnection();
            // 發送GET請求必須設置如下兩行
            conn.setDoInput(true);
            conn.setRequestMethod("GET");
            // flush輸出流的緩沖
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            logger.error("發送 GET 請求出現異常!	請求ID:"+id+"
"+e.getMessage()+"
");
        } finally {// 使用finally塊來關閉輸出流、輸入流
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                logger.error("關閉數據流出錯了!
"+ex.getMessage()+"
");
            }
        }
        // 獲得相應結果result,可以直接處理......
        
    }
    static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }

        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
    }
}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/73806.html

相關文章

  • nginx配置ssl加密(單/雙向認證、部分https

    摘要:設置協商加密算法時,優先使用我們服務端的加密套件,而不是客戶端瀏覽器的加密套件。 nginx下配置ssl本來是很簡單的,無論是去認證中心買SSL安全證書還是自簽署證書,但最近公司OA的一個需求,得以有個機會實際折騰一番。一開始采用的是全站加密,所有訪問http:80的請求強制轉換(rewrite)到https,后來自動化測試結果說響應速度太慢,https比http慢慢30倍,心想怎么可...

    kviccn 評論0 收藏0
  • 如何在Tomcat中做TLS客戶端認證

    摘要:順便一提,如果要使用客戶端認證就必須使用服務端認證。修改,添加如下可以看到我們開啟了客戶端認證,也開啟了服務端認證。所以如果要正確訪問得像下面這樣,指定證書,以及客戶端自己簽發的證書及測試我們現在用來訪問看看。 常見的https網站做的是服務端認證(server authentication),瀏覽器通過證書判斷你所訪問的https://baidu.com是否真的是百度,而不是其他人偽...

    sugarmo 評論0 收藏0
  • spy-debugger + Charles 移動端調試

    摘要:簡介移動端調試一直都是一個痛點,因為移動終端對于我們來說是一個黑盒,它無法像端一樣,我們可以通過很方便的調出開發者工具。如果沒有調試工具這種情況下我們就很難定位問題,接下來的主題就是介紹如何使用進行移動端調試。 簡介 ? 移動端調試一直都是一個痛點,因為移動終端對于我們來說是一個黑盒,它無法像PC端一樣,我們可以通過F12很方便的調出開發者工具。在開發中經常會遇到同樣一份...

    fevin 評論0 收藏0

發表評論

0條評論

songjz

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<