2012-05-30 28 views
0

這是連接到HTTPS站點針對瀏覽器和jvm處理ssl證書的區別?

  1. ,當我在瀏覽器中鍵入https://myDemoSite.com當瀏覽器與SSL證書如何應對,首先我的瀏覽器從myDemoSite.com要求證書(由於HTTPS),然後myDemoSite發送證書到瀏覽器

  2. 一旦瀏覽器接收該證書,瀏覽器會檢查它是否被驗證權威機構簽署或不喜歡威瑞信

  3. 如果是從第二個步驟,那麼作爲第三步是檢查是否CE rtificate問題有哪些用戶在瀏覽器中鍵入

相同的URL現在我連通過java程序的HTTPS站點說HttpsConnectProg1.My問題是programmei.e HttpsConnectProg1將如何處理與HTTPS站點連接發佈此 證書(雖然由此https站點頒發的證書經過驗證即由經過驗證的權威機構簽署)。

我剛剛嘗試了一個小的 程序連接到發佈認證證書的https站點。我期待一些錯誤,如sslhandshake錯誤或一些證書錯誤 (因爲我沒有將此認證證書添加到$ JAVA_HOME \ jre \ lib \ security文件夾中),但令我驚訝的是我沒有得到任何錯誤。

現在重要的問題是HttpsConnectProg1檢查步驟3由瀏覽器完成,因爲它是非常重要的一步?爲您的網站引用它

import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.Properties; 
import javax.net.ssl.HostnameVerifier; 
import javax.net.ssl.HttpsURLConnection; 
import javax.net.ssl.SSLSession; 


public class ConnectToDemoSite { 

/** 
* @param args 
*/ 
public static void main(String[] args) { 
    // TODO Auto-generated method stub 

    String urlStr = "https://www.myDemoSite.com/demo1/"; 
    URL url; 
    Properties reply = new Properties(); 
    try { 
     url = new URL(urlStr); 
     URLConnection conn = url.openConnection(); 
     if(conn instanceof HttpsURLConnection) 
     { 
     HttpsURLConnection conn1 = (HttpsURLConnection)url.openConnection(); 
      conn1.setHostnameVerifier(new HostnameVerifier() 
      {   
       public boolean verify(String hostname, SSLSession session) 
       { 
        return true; 
       } 
      }); 

     reply.load(conn1.getInputStream()); 
     } 
     else 
     { 
      conn = url.openConnection(); 
      reply.load(conn.getInputStream()); 
     } 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
    System.out.println("reply is"+reply); 



} 

} 
+0

由知名CA頒發 –

回答

2

當您對一個https:// URI與Jav​​a的連接,它使用Java Secure Socket Extension (JSSE)(除非你真的想使用SSL/TLS的自定義實現,但這是非常罕見的) 。

調整信任管理有多種方式(主要是使用自定義TrustManager s),但它會使用一定數量的合理設置。

在您的例子,該證書將使用默認SSLContext進行驗證,本身配置了默認X509TrustManager,從cacerts讀信任錨(見Customization section of the JSSE Ref. Guide表)。

默認情況下,JRE在cacerts中附帶了許多預置信任的CA證書(如大多數瀏覽器或操作系統),通常與瀏覽器中的類似。這是什麼JSSE參考。指南中提到:

重要注意事項:JDK在/ lib/security/cacerts文件中附帶有限數量的受信任根 證書。由於keytool中記錄了 ,因此如果您將此 文件用作信任庫,則您有責任維護(即, 添加/刪除)此文件中包含的證書。

根據您聯繫的服務器的證書配置, 您可能需要添加其他根證書。從相應的供應商處獲取所需的 特定根證書。

如果證書是可信的,它會檢查主機名是否對預期的URL有效。 (請注意,這不是被檢查的完整URL,但只有主機名。)

這些規則在RFC 2818 (the HTTPS specification), Section 3.1定義。 (Java 7的未實現RFC 6125呢,但規則是非常相似的,尤其是對於HTTPS)。編輯:當建立連接後,URLConnection(和潛在的SSLSession)設置與服務器的主機名。簡而言之,遵循RFC 2818中的規則,它會查看證書的主題備用名稱(SAN)擴展中的DNS條目的服務器證書,以查看它是否與爲連接設置的主機名相匹配,或查找該名稱在證書的主題DN的公用名稱(CN)中,當不存在SAN DNS條目時。

主機名驗證通常由默認的主機名驗證完成。在你的例子中,你用一個總是返回true的默認驗證器代替。因此,這種驗證實際上不會發生在您的案例中,並且所有內容都將被接受(您通過這樣做引入了安全漏洞)。

此外,在Java中所做的默認主機名驗證遵循RFC 2818比更嚴格一些瀏覽器。特別是,它不會accept IP addresses in CNs

(有關您應該使用主機名驗證總是返回true,你不應該使用的信任管理器沒有做任何事情,因爲你會看到周圍的一些例子,提供快速的同樣的原因修復一些SSL錯誤消息)

+0

兩個問題,即問題1: - 。當你告訴如果證書是可信的,它會檢查主機名是否是有效的目的URL。看起來certficates也有主機信息,因此HttpsURLConnection可以檢查證書中的主機是否與url程序相匹配正在嘗試連接。對?問題2:正如你所說在你的例子中,你已經用一個總是返回true的默認驗證器代替了,我做到了,因爲我得到了一些奇怪的錯誤,並且當時我使用了自簽名證書。我不是一個很好的做法,即使在認證CA的情況下也能返回正確的 –

+0

嗎? –

+0

我已經添加了一些關於問題1的內容:確實將主機名與證書中的一些信息(SAN擴展或CN)進行比較。關於問題2,無論如何你總是應該驗證主機名;唯一的例外是如果你想爲特定的主機綁定一個特定的證書,但是你必須事先手動驗證這個異常(類似於你想在Firefox中添加一個手動例外的檢查: d需要查看證書以檢查它是否符合您的期望,並使用其他可信賴的信息來源)。 – Bruno

相關問題