2012-04-01 43 views
22

如果我嘗試使用HttpURLConnectionHttpsURLConnection連接到「https」,有什麼區別?使用HttpURLConnection和HttpsURLConnection連接到https?

我能夠使用HttpURLConnectionHttpsURLConnection連接到「https」,所以我很困惑。我想我只能建立一個「https」開頭的連接,如果我用HttpsURLConnection?

下面是我的一些問題:

  • 如果我能打開使用到「https」開頭的連接HttpURLConnection類,我的連接仍在「https」中,還是變成了「http」?
  • 如何驗證證書?由於我在連接到「https」時沒有在我的HttpURLConnection上有任何SSLSocketFactoryHostnameVerifier,我正在使用什麼SSLSocketFactoryHostnameVerifier
  • 這是否意味着我信任一切,無論證書是否可信?

回答

17
  1. 正在使用的HTTPS連接。
  2. 默認行爲
  3. 不確定,但在下面閱讀。

我剛剛寫了一些代碼作爲測試(請參閱下面的所有方法)。什麼結束了發生的事情是URL.openConnection()調用會給你回libcore.net.http.HttpsURLConnectionImpl類。

這是HttpsURLConnection的實現,但HttpsURLConnection從HttpURLConnection繼承。所以你在工作中看到多態。

進一步看調試器,看起來該類正在使用默認的工廠方法。

的HostnameVerifier = javax.net.ssl.DefaultHostnameVerifier

的SSLSocketFactory = org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl

基於此,它看起來像默認的行爲正在被使用的。我不知道這是否意味着如果您信任所有內容,但您確實建立了HTTPS連接。

文檔有點提示連接將自動信任已知但未自簽名的CA. (見下文),我沒有測試這一點,但他們對how to accomplish that here示例代碼。

如果應用程序需要信任的證書頒發機構(CA)證書 不屬於系統的一部分,它應該通過對 HttpsURLConnection的設置SSLSocketFactory的指定其 自己X509TrustManager。

Runnable r = new Runnable() { 

    public void run() { 
     try { 
     URL test = new URL("https://www.google.com/"); 
     HttpURLConnection connection = (HttpURLConnection) test.openConnection(); 
     InputStream is = connection.getInputStream(); 
     StringWriter sw = new StringWriter(); 
     String value = new java.util.Scanner(is).useDelimiter("\\A").next(); 
     Log.w("GOOGLE", value); 
     } catch(Exception e) { 
      Log.e("Test", e.getMessage()); 
     } 
    } 

}; 

Thread t = new Thread(r); 
t.start(); 
+0

謝謝!我嘗試使用您的代碼連接到不同的https網站。 SSLSocketFactory的默認行爲是僅接受由CA簽名的證書。我收到了sun.security.validator。當我嘗試連接到證書是自簽名的網站時發生ValidatorException。感謝您的澄清! – Arci 2012-04-01 02:05:47

+1

我明白了,所以如果你知道服務器只接受HTTPS URI,你可以安全地使用'HttpURLConnection'來完成你的請求嗎? – Micro 2016-04-04 14:59:03