HTTPS 用戶端發送請求(一),https用戶端

來源:互聯網
上載者:User

HTTPS 用戶端發送請求(一),https用戶端

HTTPS 發送請求(一)

 

摘 要 JSSE是一個SSL和TLS的純Java實現,通過JSSE可以很容易地編程實現對HTTPS網站的訪問。但是,如果該網站的認證未經權威機構的驗證,JSSE將拒絕信任該認證從而不能訪問HTTPS網站。本文在簡要介紹JSSE的基礎上提出了兩種解決該問題的方法。

 

引言


  過去的十幾年,網路上已經積累了大量的Web應用。如今,無論是整合原有的Web應用系統,還是進行新的Web開發,都要求通過編程來訪問某些Web頁面。傳統的方法是使用Socket介面,但現在很多開發平台或工具如.NET、Java或PHP等都提供了簡單的Web提供者,使用這些介面很容易編程實現與Web應用系統的互動訪問,即使要訪問那些採用了HTTPS而不是HTTP的Web應用系統。

  HTTPS,即安全的超文字傳輸通訊協定 (HTTP),採用了SSL技術,被廣泛使用以保證Web應用系統的安全性。訪問Web應用的編程介面大多封裝了SSL,使得訪問HTTPS和訪問HTTP一樣簡單。但是很多中、小型應用系統或基於區域網路、校園網的應用系統所使用的認證並不是由權威的認證機構發行或者被其驗證,直接使用這些編程介面將不能訪問HTTPS。

  本文將在簡要介紹JSSE的基礎上,詳細描述使用JSSE訪問HTTPS的方法,主要說明了如何訪問帶有未經驗證認證的HTTPS網站。

  JSSE簡介

  Java安全套接擴充 (Java Secure Socket Extension, JSSE)是實現Internet安全通訊的一系列包的集合。它是一個SSL和TLS的純Java實現,可以透明地提供資料加密、伺服器認證、資訊完整性等功能,可以使我們像使用普通的通訊端一樣使用JSSE建立的安全通訊端。JSSE是一個開放的標準,不只是Sun公司才能實現一個JSSE,事實上其他公司有自己實現的JSSE。

  在深入瞭解JSSE之前,需要瞭解一個有關Java安全的概念:用戶端的TrustStore檔案。用戶端的TrustStore檔案中儲存著被用戶端所信任的伺服器的認證資訊。用戶端在進行SSL串連時,JSSE將根據這個檔案中的認證決定是否信任伺服器端的認證。

  JSSE中,有一個信任管理器類負責決定是否信任遠端的認證,這個類有如下的處理規則:

  ⑴ 如果系統屬性javax.net.sll.trustStore指定了TrustStore檔案,那麼信任管理器就去jre安裝路徑下的lib/security/目錄中尋找並使用這個檔案來檢查認證。

  ⑵ 如果該系統屬性沒有指定TrustStore檔案,它就會去jre安裝路徑下尋找預設的TrustStore檔案,這個檔案的相對路徑為:lib/security/jssecacerts。

  ⑶ 如果 jssecacerts不存在,但是cacerts存在(它隨J2SDK一起發行,含有數量有限的可信任的基本認證),那麼這個預設的TrustStore檔案就是cacerts。

  直接使用類HttpsURLConnection訪問Web頁面

      下面給出一個執行個體代碼:

URL reqURL = new URL("https://www.sun.com" ); //建立URL對象 HttpsURLConnection httpsConn = (HttpsURLConnection)reqURL.openConnection(); /*下面這段代碼實現向Web頁面發送資料,實現與網頁的互動訪問 httpsConn.setDoOutput(true); OutputStreamWriter out = new OutputStreamWriter(huc.getOutputStream(), "8859_1"); out.write( "……" ); out.flush(); out.close(); */ //取得該串連的輸入資料流,以讀取響應內容 InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream(); //讀取伺服器的響應內容並顯示 int respInt = insr.read(); while( respInt != -1){  System.out.print((char)respInt);  respInt = insr.read(); }

請仔細理解下面的這段話

    這段代碼能夠正常執行,然而把訪問的URL改為https://login.bjut.edu.cn時,程式將拋出異常javax.net.ssl.SSLException,這是由於https://login.bjut.edu.cn網站的安全性憑證不被JSSE所信任。根據JSSE簡介中對信任管理器的分析,一種解決這個問題的方法是按照信任管理器的處理規則,把網站的認證放到認證庫檔案jssecacerts中,或者把認證存放到任一TrustStore檔案中,然後設定系統屬性javax.net.sll.trustStore指向該檔案。另一種解決方案則是自己實現信任管理器類,讓它信任我們指定的認證。下面分別介紹這兩種方法。

 

將認證匯入到TrustStore檔案中


 
  Java提供了命令列工具keytool用於建立認證或者把認證從其它檔案中匯入到Java自己的TrustStore檔案中。把認證從其它檔案匯入到TrustStore檔案中的命令列格式為:

  keytool -import -file src_cer_file –keystore dest_cer_store

  其中,src_cer_file為存有認證資訊的源檔案名稱,dest_cer_store為目標TrustStore檔案。

  在使用keytool之前,首先要取得源認證檔案,這個源檔案可使用IE瀏覽器獲得,IE瀏覽器會把訪問過的HTTPS網站的認證儲存到本地。從IE瀏覽器匯出認證的方法是開啟“Internet 選項”,選擇“內容”選項卡,點擊“認證…”按鈕,在開啟的認證對話方塊中,選中一個認證,然後點擊“匯出…”按鈕,按提示一步步將該認證儲存到一檔案中。最後就可利用keytool把該認證匯入到Java的TrustStore檔案中。為了能使Java程式找到該檔案,應該把這個檔案複製到jre安裝路徑下的lib/security/目錄中。

  這樣,只需在程式中設定系統屬性javax.net.sll.trustStore指向檔案dest_cer_store,就能使JSSE信任該認證,從而使程式可以訪問使用未經驗證的認證的HTTPS網站。

  使用這種方法,編程非常簡單,但需要手工匯出伺服器的認證。當伺服器憑證經常變化時,就需要經常進行手工匯出認證的操作。下面介紹的實現X509認證信任管理器類的方法將避免手工匯出認證的問題。


 X509認證信任管理器類的實現及應用


  在JSSE中,認證信任管理器類就是實現了介面X509TrustManager的類。我們可以自己實現該介面,讓它信任我們指定的認證。

  介面X509TrustManager有下述三個公有的方法需要我們實現:

  ⑴ oid checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException

  該方法檢查用戶端的認證,若不信任該認證則拋出異常。由於我們不需要對用戶端進行認證,因此我們只需要執行預設的信任管理器的這個方法。JSSE中,預設的信任管理器類為TrustManager。

  ⑵ oid checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException

  該方法檢查伺服器的認證,若不信任該認證同樣拋出異常。通過自己實現該方法,可以使之信任我們指定的任何認證。在實現該方法時,也可以簡單的不做任何處理,即一個空的函數體,由於不會拋出異常,它就會信任任何認證。

  ⑶ X509Certificate[] getAcceptedIssuers()

  返回受信任的X509認證數組       自己實現了信任管理器類,如何使用呢?類HttpsURLConnection似乎並沒有提供方法設定信任管理器。其實,HttpsURLConnection通過SSLSocket來建立與HTTPS的安全連線,SSLSocket對象是由SSLSocketFactory產生的。HttpsURLConnection提供了方法setSSLSocketFactory(SSLSocketFactory)設定它使用的SSLSocketFactory對象。SSLSocketFactory通過SSLContext對象來獲得,在初始化SSLContext對象時,可指定信任管理器對象。

       假設自己實現的X509TrustManager類的類名為:MyX509TrustManager,下面的代碼片斷說明了如何使用MyX509TrustManager:

//建立SSLContext對象,並使用我們指定的信任管理器初始化 TrustManager[] tm = {new MyX509TrustManager ()}; SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); //從上述SSLContext對象中得到SSLSocketFactory對象 SSLSocketFactory ssf = sslContext.getSocketFactory(); //建立HttpsURLConnection對象,並設定其SSLSocketFactory對象 HttpsURLConnection httpsConn = (HttpsURLConnection)myURL.openConnection(); httpsConn.setSSLSocketFactory(ssf);


這樣,HttpsURLConnection對象就可以正常串連HTTPS了,無論其認證是否經權威機構的驗證,只要實現了介面X509TrustManager的類MyX509TrustManager信任該認證。

 

******************************對以上程式不理解的,後面將會有全部程式的講解******************************

 

小結

  本文主要介紹了在HTTPS的認證未經權威機構認證的情況下,訪問HTTPS網站的兩種方法,一種方法是把該認證匯入到Java的TrustStore檔案中,另一種是自己實現並覆蓋JSSE預設的認證信任管理器類。兩種方法各有優缺點,第一種方法不會影響JSSE的安全性,但需要手工匯入認證;第二種方法雖然不用手工匯入認證,但需要小心使用,否則會帶來一些安全隱患

 

下一篇將實現完整的https開發

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.