2012-10-28 106 views
3

我需要禁用僅用於測試的Java證書驗證。所以我瞭解風險。我用下面的教程:http://www.rgagnon.com/javadetails/java-fix-certificate-problem-in-HTTPS.html如何在java中禁用證書驗證

因此,代碼爲:

import java.io.InputStreamReader; 
import java.io.Reader; 
import java.net.URL; 
import java.net.URLConnection; 

import javax.net.ssl.HostnameVerifier; 
import javax.net.ssl.HttpsURLConnection; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSession; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 
import java.security.cert.X509Certificate; 

public class Cert { 
    public static void main(String[] args) throws Exception { 
    /* 
    * fix for 
    * Exception in thread "main" javax.net.ssl.SSLHandshakeException: 
    *  sun.security.validator.ValidatorException: 
    *   PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
    *    unable to find valid certification path to requested target 
    */ 
    TrustManager[] trustAllCerts = new TrustManager[] { 
     new X509TrustManager() { 
      public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
      return null; 
      } 

      public void checkClientTrusted(X509Certificate[] certs, String authType) { } 

      public void checkServerTrusted(X509Certificate[] certs, String authType) { } 

     } 
    }; 

    SSLContext sc = SSLContext.getInstance("SSL"); 
    sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 

    // Create all-trusting host name verifier 
    HostnameVerifier allHostsValid = new HostnameVerifier() { 
     public boolean verify(String hostname, SSLSession session) { 
      return true; 
     } 
    }; 
    // Install the all-trusting host verifier 
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); 
    /* 
    * end of the fix 
    */ 

    URL url = new URL("https://www.nakov.com:2083/"); 
    URLConnection con = url.openConnection(); 
    Reader reader = new InputStreamReader(con.getInputStream()); 
    while (true) { 
     int ch = reader.read(); 
     if (ch==-1) { 
     break; 
     } 
     System.out.print((char)ch); 
    } 
     } 
    } 

我仍然得到下面的錯誤。任何身體可以幫助嗎?

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 401 for URL: https://www.nakov.com:2083/ 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1615) 
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254) 
    at MainProject.Cert.main(Cert.java:56) 
+0

我有一個類似的代碼,但是當我運行我的應用程序時,它給了我錯誤說:java.lang.classcastexception:java.lang.string不能轉換爲java.lang.boolean。我相信這個錯誤來自verify(String,SSLSession)方法,它返回一個布爾值,但由於某種原因,在我的情況下,它返回一個null?有任何想法嗎? – codeinprogress

回答

2

不要打擾你的代碼禁用它,你可以將證書只需添加到您的測試機信任庫和100%肯定你沒有禁用檢查船舶構建。

+0

我需要以編程方式執行此操作。 –

+1

@JuryA爲什麼?爲什麼你會想要寫有條件不安全的代碼?不要這樣做。 – EJP

+0

我也必須這樣做,因爲它是我爲多個客戶端編寫的軟件,它們將使用所有不同的證書連接到他們自己的服務器。我並不關心證書,因爲鏈接是完全可信的。 –

4

「修復」和異常顯得無關:修復會禁用客戶端對服務器證書的驗證,而異常表示服務器認爲客戶端未被授權訪問該URL。

+0

但是,當我將URL添加到我的瀏覽器時,我可以訪問它。唯一的事情就是Firefox會針對自簽名證書提醒我。 –

+1

然後,我會檢查firefox發送的http請求(例如用螢火蟲的網絡標籤)以發現差異(cookie?用戶代理標頭?不同的http代理?...?)。 – meriton

3

這不會解決問題。 401通過HTTPS和SSL傳輸,因此證書工作正常。

無論如何我強烈建議你不要這樣做。您不希望在測試和生產中執行不同的代碼。測試代碼會泄漏到生產環境中並危及安全性。測試不安全代碼沒有意義。

1

正如其他人所說,錯誤401意味着您確實建立了SSL連接,發送了您的請求並被回送了401錯誤。所以你的SSL代碼很好。

當您在瀏覽器中打開此頁面時,您是否收到用戶名/密碼提示?也許自動登錄?如果是這種情況,我會說你的代碼缺少這個基本的認證或類似的。