世界因你而精彩  
          日歷
          <2015年7月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678
          統(tǒng)計(jì)
          • 隨筆 - 169
          • 文章 - 1
          • 評(píng)論 - 138
          • 引用 - 0

          導(dǎo)航

          常用鏈接

          留言簿(9)

          隨筆分類(lèi)(163)

          隨筆檔案(154)

          文章檔案(1)

          新聞檔案(1)

          相冊(cè)

          收藏夾(1)

          個(gè)人雜雜

          友情鏈接

          自學(xué)考試

          資料搜索

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 360135
          • 排名 - 153

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

           
          摘 要 JSSE是一個(gè)SSL和TLS的純Java實(shí)現(xiàn),通過(guò)JSSE可以很容易地編程實(shí)現(xiàn)對(duì)HTTPS站點(diǎn)的訪(fǎng)問(wèn)。但是,如果該站點(diǎn)的證書(shū)未經(jīng)權(quán)威機(jī)構(gòu)的驗(yàn)證,JSSE將拒絕信任該證書(shū)從而不能訪(fǎng)問(wèn)HTTPS站點(diǎn)。本文在簡(jiǎn)要介紹JSSE的基礎(chǔ)上提出了兩種解決該問(wèn)題的方法。

            引言

            過(guò)去的十幾年,網(wǎng)絡(luò)上已經(jīng)積累了大量的Web應(yīng)用。如今,無(wú)論是整合原有的Web應(yīng)用系統(tǒng),還是進(jìn)行新的Web開(kāi)發(fā),都要求通過(guò)編程來(lái)訪(fǎng)問(wèn)某些Web頁(yè)面。傳統(tǒng)的方法是使用Socket接口,但現(xiàn)在很多開(kāi)發(fā)平臺(tái)或工具如.NET、Java或PHP等都提供了簡(jiǎn)單的Web訪(fǎng)問(wèn)接口,使用這些接口很容易編程實(shí)現(xiàn)與Web應(yīng)用系統(tǒng)的交互訪(fǎng)問(wèn),即使要訪(fǎng)問(wèn)那些采用了HTTPS而不是HTTP的Web應(yīng)用系統(tǒng)。

            HTTPS,即安全的超文本傳輸協(xié)議,采用了SSL技術(shù),被廣泛使用以保證Web應(yīng)用系統(tǒng)的安全性。訪(fǎng)問(wèn)Web應(yīng)用的編程接口大多封裝了SSL,使得訪(fǎng)問(wèn)HTTPS和訪(fǎng)問(wèn)HTTP一樣簡(jiǎn)單。但是很多中、小型應(yīng)用系統(tǒng)或基于局域網(wǎng)、校園網(wǎng)的應(yīng)用系統(tǒng)所使用的證書(shū)并不是由權(quán)威的認(rèn)證機(jī)構(gòu)發(fā)行或者被其驗(yàn)證,直接使用這些編程接口將不能訪(fǎng)問(wèn)HTTPS。

            本文將在簡(jiǎn)要介紹JSSE的基礎(chǔ)上,詳細(xì)描述使用JSSE訪(fǎng)問(wèn)HTTPS的方法,主要說(shuō)明了如何訪(fǎng)問(wèn)帶有未經(jīng)驗(yàn)證證書(shū)的HTTPS站點(diǎn)。

            JSSE簡(jiǎn)介

            Java安全套接擴(kuò)展 (Java Secure Socket Extension, JSSE)是實(shí)現(xiàn)Internet安全通信的一系列包的集合。它是一個(gè)SSL和TLS的純Java實(shí)現(xiàn),可以透明地提供數(shù)據(jù)加密、服務(wù)器認(rèn)證、信息完整性等功能,可以使我們像使用普通的套接字一樣使用JSSE建立的安全套接字。JSSE是一個(gè)開(kāi)放的標(biāo)準(zhǔn),不只是Sun公司才能實(shí)現(xiàn)一個(gè)JSSE,事實(shí)上其他公司有自己實(shí)現(xiàn)的JSSE。

            在深入了解JSSE之前,需要了解一個(gè)有關(guān)Java安全的概念:客戶(hù)端的TrustStore文件。客戶(hù)端的TrustStore文件中保存著被客戶(hù)端所信任的服務(wù)器的證書(shū)信息。客戶(hù)端在進(jìn)行SSL連接時(shí),JSSE將根據(jù)這個(gè)文件中的證書(shū)決定是否信任服務(wù)器端的證書(shū)。

            JSSE中,有一個(gè)信任管理器類(lèi)負(fù)責(zé)決定是否信任遠(yuǎn)端的證書(shū),這個(gè)類(lèi)有如下的處理規(guī)則:

            ⑴ 果系統(tǒng)屬性javax.net.sll.trustStore指定了TrustStore文件,那么信任管理器就去jre安裝路徑下的lib/security/目錄中尋找并使用這個(gè)文件來(lái)檢查證書(shū)。

            ⑵ 果該系統(tǒng)屬性沒(méi)有指定TrustStore文件,它就會(huì)去jre安裝路徑下尋找默認(rèn)的TrustStore文件,這個(gè)文件的相對(duì)路徑為:lib/security/jssecacerts。

            ⑶ 如果 jssecacerts不存在,但是cacerts存在(它隨J2SDK一起發(fā)行,含有數(shù)量有限的可信任的基本證書(shū)),那么這個(gè)默認(rèn)的TrustStore文件就是cacerts。

            直接使用類(lèi)HttpsURLConnection訪(fǎng)問(wèn)Web頁(yè)面

            Java提供了一種非常簡(jiǎn)潔的方法來(lái)訪(fǎng)問(wèn)HTTPS網(wǎng)頁(yè),即使用類(lèi)HttpsURLConnection、URL等。這幾個(gè)類(lèi)為支持HTTPS對(duì)JSSE相關(guān)類(lèi)做了進(jìn)一步的封裝,例子如下所示:

          URL reqURL = new URL("https://www.sun.com" ); //創(chuàng)建URL對(duì)象
          HttpsURLConnection httpsConn = (HttpsURLConnection)reqURL.openConnection();

          /*下面這段代碼實(shí)現(xiàn)向Web頁(yè)面發(fā)送數(shù)據(jù),實(shí)現(xiàn)與網(wǎng)頁(yè)的交互訪(fǎng)問(wèn)
          httpsConn.setDoOutput(true);
          OutputStreamWriter out = new OutputStreamWriter(huc.getOutputStream(), "8859_1");
          out.write( "……" );
          out.flush();
          out.close();
          */

          //取得該連接的輸入流,以讀取響應(yīng)內(nèi)容
          InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream();

          //讀取服務(wù)器的響應(yīng)內(nèi)容并顯示
          int respInt = insr.read();
          while( respInt != -1){
           System.out.print((char)respInt);
           respInt = insr.read();
          }

            這段代碼能夠正常執(zhí)行,然而把訪(fǎng)問(wèn)的URL改為https://login.bjut.edu.cn時(shí),程序?qū)伋霎惓avax.net.ssl.SSLException,這是由于https://login.bjut.edu.cn站點(diǎn)的安全證書(shū)不被JSSE所信任。根據(jù)JSSE簡(jiǎn)介中對(duì)信任管理器的分析,一種解決這個(gè)問(wèn)題的方法是按照信任管理器的處理規(guī)則,把站點(diǎn)的證書(shū)放到證書(shū)庫(kù)文件jssecacerts中,或者把證書(shū)存放到任一TrustStore文件中,然后設(shè)置系統(tǒng)屬性javax.net.sll.trustStore指向該文件。另一種解決方法則是自己實(shí)現(xiàn)信任管理器類(lèi),讓它信任我們指定的證書(shū)。下面分別介紹這兩種方法。

            將證書(shū)導(dǎo)入到TrustStore文件中

            Java提供了命令行工具keytool用于創(chuàng)建證書(shū)或者把證書(shū)從其它文件中導(dǎo)入到Java自己的TrustStore文件中。把證書(shū)從其它文件導(dǎo)入到TrustStore文件中的命令行格式為:

            keytool -import -file src_cer_file –keystore dest_cer_store

            其中,src_cer_file為存有證書(shū)信息的源文件名,dest_cer_store為目標(biāo)TrustStore文件。

            在使用keytool之前,首先要取得源證書(shū)文件,這個(gè)源文件可使用IE瀏覽器獲得,IE瀏覽器會(huì)把訪(fǎng)問(wèn)過(guò)的HTTPS站點(diǎn)的證書(shū)保存到本地。從IE瀏覽器導(dǎo)出證書(shū)的方法是打開(kāi)“Internet 選項(xiàng)”,選擇“內(nèi)容”選項(xiàng)卡,點(diǎn)擊“證書(shū)…”按鈕,在打開(kāi)的證書(shū)對(duì)話(huà)框中,選中一個(gè)證書(shū),然后點(diǎn)擊“導(dǎo)出…”按鈕,按提示一步步將該證書(shū)保存到一文件中。最后就可利用keytool把該證書(shū)導(dǎo)入到Java的TrustStore文件中。為了能使Java程序找到該文件,應(yīng)該把這個(gè)文件復(fù)制到j(luò)re安裝路徑下的lib/security/目錄中。

            這樣,只需在程序中設(shè)置系統(tǒng)屬性javax.net.sll.trustStore指向文件dest_cer_store,就能使JSSE信任該證書(shū),從而使程序可以訪(fǎng)問(wèn)使用未經(jīng)驗(yàn)證的證書(shū)的HTTPS站點(diǎn)。

            使用這種方法,編程非常簡(jiǎn)單,但需要手工導(dǎo)出服務(wù)器的證書(shū)。當(dāng)服務(wù)器證書(shū)經(jīng)常變化時(shí),就需要經(jīng)常進(jìn)行手工導(dǎo)出證書(shū)的操作。下面介紹的實(shí)現(xiàn)X509證書(shū)信任管理器類(lèi)的方法將避免手工導(dǎo)出證書(shū)的問(wèn)題。
          X509證書(shū)信任管理器類(lèi)的實(shí)現(xiàn)及應(yīng)用

            在JSSE中,證書(shū)信任管理器類(lèi)就是實(shí)現(xiàn)了接口X509TrustManager的類(lèi)。我們可以自己實(shí)現(xiàn)該接口,讓它信任我們指定的證書(shū)。

            接口X509TrustManager有下述三個(gè)公有的方法需要我們實(shí)現(xiàn):

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

            該方法檢查客戶(hù)端的證書(shū),若不信任該證書(shū)則拋出異常。由于我們不需要對(duì)客戶(hù)端進(jìn)行認(rèn)證,因此我們只需要執(zhí)行默認(rèn)的信任管理器的這個(gè)方法。JSSE中,默認(rèn)的信任管理器類(lèi)為T(mén)rustManager。

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

            該方法檢查服務(wù)器的證書(shū),若不信任該證書(shū)同樣拋出異常。通過(guò)自己實(shí)現(xiàn)該方法,可以使之信任我們指定的任何證書(shū)。在實(shí)現(xiàn)該方法時(shí),也可以簡(jiǎn)單的不做任何處理,即一個(gè)空的函數(shù)體,由于不會(huì)拋出異常,它就會(huì)信任任何證書(shū)。

            ⑶ X509Certificate[] getAcceptedIssuers()

            返回受信任的X509證書(shū)數(shù)組。

            自己實(shí)現(xiàn)了信任管理器類(lèi),如何使用呢?類(lèi)HttpsURLConnection似乎并沒(méi)有提供方法設(shè)置信任管理器。其實(shí),HttpsURLConnection通過(guò)SSLSocket來(lái)建立與HTTPS的安全連接,SSLSocket對(duì)象是由SSLSocketFactory生成的。HttpsURLConnection提供了方法setSSLSocketFactory(SSLSocketFactory)設(shè)置它使用的SSLSocketFactory對(duì)象。SSLSocketFactory通過(guò)SSLContext對(duì)象來(lái)獲得,在初始化SSLContext對(duì)象時(shí),可指定信任管理器對(duì)象。下面用一個(gè)圖簡(jiǎn)單表示這幾個(gè)JSSE類(lèi)的關(guān)系:


          圖1 部分JSSE類(lèi)的關(guān)系圖

            假設(shè)自己實(shí)現(xiàn)的X509TrustManager類(lèi)的類(lèi)名為:MyX509TrustManager,下面的代碼片斷說(shuō)明了如何使用MyX509TrustManager:

          //創(chuàng)建SSLContext對(duì)象,并使用我們指定的信任管理器初始化
          TrustManager[] tm = {new MyX509TrustManager ()};
          SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE");
          sslContext.init(null, tm, new java.security.SecureRandom());

          //從上述SSLContext對(duì)象中得到SSLSocketFactory對(duì)象
          SSLSocketFactory ssf = sslContext.getSocketFactory();

          //創(chuàng)建HttpsURLConnection對(duì)象,并設(shè)置其SSLSocketFactory對(duì)象
          HttpsURLConnection httpsConn = (HttpsURLConnection)myURL.openConnection();
          httpsConn.setSSLSocketFactory(ssf);

            這樣,HttpsURLConnection對(duì)象就可以正常連接HTTPS了,無(wú)論其證書(shū)是否經(jīng)權(quán)威機(jī)構(gòu)的驗(yàn)證,只要實(shí)現(xiàn)了接口X509TrustManager的類(lèi)MyX509TrustManager信任該證書(shū)。

            小結(jié)

            本文主要介紹了在HTTPS的證書(shū)未經(jīng)權(quán)威機(jī)構(gòu)認(rèn)證的情況下,訪(fǎng)問(wèn)HTTPS站點(diǎn)的兩種方法,一種方法是把該證書(shū)導(dǎo)入到Java的TrustStore文件中,另一種是自己實(shí)現(xiàn)并覆蓋JSSE缺省的證書(shū)信任管理器類(lèi)。兩種方法各有優(yōu)缺點(diǎn),第一種方法不會(huì)影響JSSE的安全性,但需要手工導(dǎo)入證書(shū);第二種方法雖然不用手工導(dǎo)入證書(shū),但需要小心使用,否則會(huì)帶來(lái)一些安全隱患。
          posted on 2006-06-29 16:13 張秀蘭 閱讀(11091) 評(píng)論(9)  編輯  收藏
          評(píng)論:

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
           
          Copyright © 張秀蘭 Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 龙南县| 屯留县| 新乡县| 伊通| 峨眉山市| 乡城县| 汤原县| 忻城县| 北京市| 无锡市| 龙南县| 华亭县| 杭州市| 永定县| 枣阳市| 新邵县| 瑞丽市| 双牌县| 大方县| 丰都县| 信宜市| 北碚区| 望奎县| 清徐县| 囊谦县| 永定县| 南和县| 台山市| 平乡县| 古丈县| 富蕴县| 连城县| 普安县| 丹阳市| 望城县| 夏河县| 科技| 隆尧县| 涡阳县| 旌德县| 万年县|