2013-09-25 62 views
1

我需要忽略PKIX路徑建設例外忽略出現SSLHandshakeException只爲一個特定的服務器

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

我知道如何寫我自己的類實現X509TrustManager要做到這一點,我總是return trueisServerTrusted

但這是相當廣泛的。我的代碼將成爲更大項目的一部分。我不希望其他所有事情都受到我替換信託經理的影響。

我總是會連接到一個固定的域名,即「www.myws.com」。我只想忽略SSLHandshakeException只能連接到「www.myws.com」。

是這樣的可能嗎?

+0

的[實施X509TrustManager可能重複 - 通過該驗證的一部分,現有的驗證](http://stackoverflow.com/questions/19005318/implementing-x509trustmanager-passing-on-part-of-the-verification-to-existing) – Bruno

+0

這是*非常類似於你的其他問題,但似乎集中更多關於如何設置特定信任管理器的信息大連接。你使用哪些庫? – Bruno

+0

@布魯諾這與我的其他問題類似。但肯定不是重複的。從2個不同的角度接近相同的問題。當域名與Cert中的主題不匹配時,會拋出SSL異常。在這裏我試圖根據域名過濾,那裏我試圖根據主題進行過濾。對於兩個問題的答案几乎沒有可能是相同的,因爲我認爲TrustMananger完全沒有獲取服務器的域名。我認爲域名比較會在TrustManager被要求驗證證書是否由受信任的CA簽名之前(或之後)發生。 – user93353

回答

0

由於我認爲TrustMananger根本不知道服務器的域名,所以2個問題的答案几乎沒有可能相同。

實際上,信任管理器可以獲取您之後的主機名的名稱。儘管這取決於許多因素。

  • 就讓我們假設你的客戶是在Java 7中

    運行如果按照同樣的方法this other answer但使用X509ExtendedTrustManager(在Java 7中引入的,而不是一個普通的X509TrustManager),你會得到額外的重載方法,它們也會給你當前的SSLSocketSSLEngine

    SSLContext使得使用這些方法時,與X509ExtendedTrustManager實例初始化,但不能當它是一個普通的X509TrustManager,所以它必須使這些調用之前檢查類型(見快速測試這個答案,基地結束the code in that answer)。

    我不知道這個行爲是在哪裏指定的API。在JSSE Reference Guide中似乎沒有關於X509ExtendedTrustManager類型檢查的任何信息。 確保使用擴展方法的一種方法是設置enpoint identification algorithm (like HTTPS) in your SSLParameters,但您需要對客戶端代碼及其使用的庫進行某種程度的控制。 (這也是Java 7中引入的一個功能)

    從那裏獲得的SSLSocketSSLEngine,你可以得到SSLSession和對等主機,所以你可以有執行檢查。 (請注意,如果創建SSLSocketSSLEngine的庫未使用通過該名稱的方法之一作爲String,而是通過了InetAddress,則主機名稱可能與預期的不匹配。您也將丟失SNI這種情況)。

    然後,您可以在默認的SSLContext(使用setDefault(...))中使用這樣的信任管理器。

  • 如果您不想影響默認SSLContext(這種調整的明智選擇),您需要弄清楚客戶端庫如何在每個連接上使用不同的一個。這完全取決於使用的內容。

    對於傳統的URLConnection,將其作爲HttpsURLConnection進行投射,並將其設置爲SSLSocketFactory作爲自定義SSLContext的一個版本。


使用了哪些方法將取決於您是否已實例化的X509ExtendedTrustManagerX509TrustManager

X509TrustManager customTm = new X509ExtendedTrustManager() { 
    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     return finalTm.getAcceptedIssuers(); 
    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] chain, 
      String authType) throws CertificateException { 
     System.out 
       .println("Current method: checkServerTrusted(chain, authType)"); 
     finalTm.checkServerTrusted(chain, authType); 
    } 

    //@Override 
    public void checkServerTrusted(X509Certificate[] chain, 
      String authType, Socket socket) throws CertificateException { 
     System.out 
       .println("Current method: checkServerTrusted(chain, authType, socket)"); 
     finalTm.checkServerTrusted(chain, authType, socket); 
    } 

    //@Override 
    public void checkServerTrusted(X509Certificate[] chain, 
      String authType, SSLEngine engine) 
      throws CertificateException { 
     System.out 
       .println("Current method: checkServerTrusted(chain, authType, engine)"); 
     finalTm.checkServerTrusted(chain, authType, engine); 
    } 

    // Same for client-related methods. 
};