關於HostnameVerifier接口的解讀


在項目中我們需要調用https接口請求。我們使用httpClient,構建HttpClient對象時涉及到使用HostnameVerifier接口實例。

HostnameVerifier接口定義如下:

1 public abstract interface HostnameVerifier
2 {
3   public abstract boolean verify(String paramString, SSLSession paramSSLSession);
4 }

僅一個方法,參數paramString為請求地址host;參數paramSSLSession是當前請求的SSLSession,可以獲取到證書列表,默認實現類DefaultHostnameVerifier的實現如下:

 1     @Override
 2     public boolean verify(final String host, final SSLSession session) {
 3         try {
 4             final Certificate[] certs = session.getPeerCertificates();
 5             final X509Certificate x509 = (X509Certificate) certs[0];
 6             verify(host, x509);
 7             return true;
 8         } catch (final SSLException ex) {
 9             if (log.isDebugEnabled()) {
10                 log.debug(ex.getMessage(), ex);
11             }
12             return false;
13         }
14     }

接口是用於主機名驗證,准確說是驗證服務器ca證書中的host是否和請求地址host一致,為什么要進行主機名驗證呢?其實目的是加強一層安全防護,防止惡意程序利用中間人攻擊。

什么是中間人攻擊?

假設有一個攻擊者處於“瀏覽器”和“網站服務器”的通訊線路之間(比如公共WIFI),它的攻擊過程如下:

  1. 服務器向客戶端發送公鑰。
  2. 攻擊者截獲公鑰,保留在自己手上。
    然后攻擊者自己生成一個【偽造的】公鑰,發給客戶端。
  3. 客戶端收到偽造的公鑰后,生成加密hash值發給服務器。
  4. 攻擊者獲得加密hash值,用自己的私鑰解密獲得真秘鑰。
    同時生成假的加密hash值,發給服務器。
  5. 服務器用私鑰解密獲得假秘鑰。

FIddler就是通過這種方式截獲HTTPS信息。

上面問題的根源是因為“缺乏身份認證機制”,需要驗證【偽造的】公鑰是否是網站服務器的,我們客戶端httpClient可以通過驗證公鑰中的host,防止被中間人攻擊。

參考資料:

https://blog.csdn.net/fanjint/article/details/81985004

https://www.jianshu.com/p/ad4c7ce94518


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM