http與https網(wǎng)絡(luò)請求

HTTPS胚嘲,即安全的超文本傳輸協(xié)議其爵,采用了SSL技術(shù)饭于,被廣泛使用以保證Web應(yīng)用系統(tǒng)的安全性。訪問Web應(yīng)用的編程接口大多封裝了SSL撬码,使得訪問HTTPS和訪問HTTP一樣簡單儿倒。

本文將在簡要介紹JSSE的基礎(chǔ)上,詳細描述使用JSSE訪問HTTPS的方法呜笑,主要說明了如何訪問帶有未經(jīng)驗證證書的HTTPS站點夫否。

Java安全套接擴展 (Java Secure Socket Extension, JSSE)是實現(xiàn)Internet安全通信的一系列包的集合。它是一個SSL和TLS的純Java實現(xiàn)叫胁,可以透明地提供數(shù)據(jù)加密凰慈、服務(wù)器認證、信息完整性等功能驼鹅,可以使我們像使用普通的套接字一樣使用JSSE建立的安全套接字微谓。JSSE是一個開放的標準,不只是Sun公司才能實現(xiàn)一個JSSE输钩,事實上其他公司有自己實現(xiàn)的JSSE豺型。
在深入了解JSSE之前,需要了解一個有關(guān)Java安全的概念:客戶端的TrustStore文件买乃∫霭保客戶端的TrustStore文件中保存著被客戶端所信任的服務(wù)器的證書信息〖粞椋客戶端在進行SSL連接時肴焊,JSSE將根據(jù)這個文件中的證書決定是否信任服務(wù)器端的證書。

JSSE中功戚,有一個信任管理器類負責(zé)決定是否信任遠端的證書娶眷,這個類有如下的處理規(guī)則:

1 ) 如果系統(tǒng)屬性javax.net.sll.trustStore指定了TrustStore文件,那么信任管理器就去jre安裝路徑下的lib/security/目錄中尋找并使用這個文件來檢查證書疫铜。
2 ) 如果該系統(tǒng)屬性沒有指定TrustStore文件茂浮,它就會去jre安裝路徑下尋找默認的TrustStore文件,這個文件的相對路徑為:lib/security/jssecacerts壳咕。
3 ) 如果 jssecacerts不存在席揽,但是cacerts存在(它隨J2SDK一起發(fā)行,含有數(shù)量有限的可信任的基本證書)谓厘,那么這個默認的TrustStore文件就是cacerts幌羞。

直接使用類HttpsURLConnection訪問Web頁面

Java提供了一種非常簡潔的方法來訪問HTTPS網(wǎng)頁,即使用類HttpsURLConnection竟稳、URL等属桦。這幾個類為支持HTTPS對JSSE相關(guān)類做了進一步的封裝熊痴,例子如下所示:

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

/*下面這段代碼實現(xiàn)向Web頁面發(fā)送數(shù)據(jù),實現(xiàn)與網(wǎng)頁的交互訪問
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í)行果善,然而把訪問的URL改為https://login.bjut.edu.cn 時,程序?qū)伋霎惓?a target="_blank" rel="nofollow">javax.net.ssl.SSLException系谐,這是由于https://login.bjut.edu.cn 站點的安全證書不被JSSE所信任巾陕。根據(jù)JSSE簡介中對信任管理器的分析,一種解決這個問題的方法是按照信任管理器的處理規(guī)則纪他,把站點的證書放到證書庫文件jssecacerts中鄙煤,或者把證書存放到任一TrustStore文件中,然后設(shè)置系統(tǒng)屬性javax.net.sll.trustStore指向該文件茶袒。另一種解決方法則是自己實現(xiàn)信任管理器類梯刚,讓它信任我們指定的證書。下面分別介紹這兩種方法薪寓。

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

Java提供了命令行工具keytool用于創(chuàng)建證書或者把證書從其它文件中導(dǎo)入到Java自己的TrustStore文件中亡资。把證書從其它文件導(dǎo)入到TrustStore文件中的命令行格式為:
keytool -import -file src_cer_file –keystore dest_cer_store
其中,src_cer_file為存有證書信息的源文件名预愤,dest_cer_store為目標TrustStore文件沟于。
  在使用keytool之前,首先要取得源證書文件植康,這個源文件可使用IE瀏覽器獲得,IE瀏覽器會把訪問過的HTTPS站點的證書保存到本地展懈。從IE瀏覽器導(dǎo)出證書的方法是打開“Internet 選項”销睁,選擇“內(nèi)容”選項卡,點擊“證書…”按鈕存崖,在打開的證書對話框中冻记,選中一個證書,然后點擊“導(dǎo)出…”按鈕来惧,按提示一步步將該證書保存到一文件中冗栗。最后就可利用keytool把該證書導(dǎo)入到Java的TrustStore文件中。為了能使Java程序找到該文件供搀,應(yīng)該把這個文件復(fù)制到j(luò)re安裝路徑下的lib/security/目錄中隅居。

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

使用這種方法屿脐,編程非常簡單涕蚤,但需要手工導(dǎo)出服務(wù)器的證書宪卿。當(dāng)服務(wù)器證書經(jīng)常變化時,就需要經(jīng)常進行手工導(dǎo)出證書的操作万栅。下面介紹的實現(xiàn)X509證書信任管理器類的方法將避免手工導(dǎo)出證書的問題佑钾。

X509證書信任管理器類的實現(xiàn)及應(yīng)用

在JSSE中,證書信任管理器類就是實現(xiàn)了接口X509TrustManager的類烦粒。我們可以自己實現(xiàn)該接口休溶,讓它信任我們指定的證書。

接口X509TrustManager有下述三個公有的方法需要我們實現(xiàn):
⑴ void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException
該方法檢查客戶端的證書撒遣,若不信任該證書則拋出異常邮偎。由于我們不需要對客戶端進行認證,因此我們只需要執(zhí)行默認的信任管理器的這個方法义黎。JSSE中禾进,默認的信任管理器類為TrustManager。
⑵void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException

該方法檢查服務(wù)器的證書廉涕,若不信任該證書同樣拋出異常泻云。通過自己實現(xiàn)該方法,可以使之信任我們指定的任何證書狐蜕。在實現(xiàn)該方法時宠纯,也可以簡單的不做任何處理,即一個空的函數(shù)體层释,由于不會拋出異常婆瓜,它就會信任任何證書。

⑶ X509Certificate[] getAcceptedIssuers()
返回受信任的X509證書數(shù)組贡羔。

自己實現(xiàn)了信任管理器類廉白,如何使用呢?類HttpsURLConnection似乎并沒有提供方法設(shè)置信任管理器乖寒。其實猴蹂,HttpsURLConnection通過SSLSocket來建立與HTTPS的安全連接,SSLSocket對象是由SSLSocketFactory生成的楣嘁。HttpsURLConnection提供了方法setSSLSocketFactory(SSLSocketFactory)設(shè)置它使用的SSLSocketFactory對象磅轻。SSLSocketFactory通過SSLContext對象來獲得,在初始化SSLContext對象時逐虚,可指定信任管理器對象聋溜。下面用一個圖簡單表示這幾個JSSE類的關(guān)系:


image

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

//創(chuàng)建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();

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

這樣,HttpsURLConnection對象就可以正常連接HTTPS了涤伐,無論其證書是否經(jīng)權(quán)威機構(gòu)的驗證馒胆,只要實現(xiàn)了接口X509TrustManager的類MyX509TrustManager信任該證書缨称。

小結(jié)

本文主要介紹了在HTTPS的證書未經(jīng)權(quán)威機構(gòu)認證的情況下,訪問HTTPS站點的兩種方法祝迂,一種方法是把該證書導(dǎo)入到Java的TrustStore文件中睦尽,另一種是自己實現(xiàn)并覆蓋JSSE缺省的證書信任管理器類。兩種方法各有優(yōu)缺點型雳,第一種方法不會影響JSSE的安全性当凡,但需要手工導(dǎo)入證書;第二種方法雖然不用手工導(dǎo)入證書纠俭,但需要小心使用沿量,否則會帶來一些安全隱患。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冤荆,一起剝皮案震驚了整個濱河市朴则,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌钓简,老刑警劉巖乌妒,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異外邓,居然都是意外死亡撤蚊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門损话,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侦啸,“玉大人,你說我怎么就攤上這事丧枪∑ブ校” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵豪诲,是天一觀的道長。 經(jīng)常有香客問我挂绰,道長屎篱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任葵蒂,我火速辦了婚禮交播,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘践付。我一直安慰自己秦士,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布永高。 她就那樣靜靜地躺著隧土,像睡著了一般提针。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上曹傀,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天辐脖,我揣著相機與錄音,去河邊找鬼皆愉。 笑死嗜价,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的幕庐。 我是一名探鬼主播久锥,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼异剥!你這毒婦竟也來了瑟由?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤届吁,失蹤者是張志新(化名)和其女友劉穎错妖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疚沐,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡暂氯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了亮蛔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痴施。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖究流,靈堂內(nèi)的尸體忽然破棺而出辣吃,到底是詐尸還是另有隱情,我是刑警寧澤芬探,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布神得,位于F島的核電站,受9級特大地震影響偷仿,放射性物質(zhì)發(fā)生泄漏哩簿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一酝静、第九天 我趴在偏房一處隱蔽的房頂上張望节榜。 院中可真熱鬧,春花似錦别智、人聲如沸宗苍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讳窟。三九已至让歼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挪钓,已是汗流浹背是越。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碌上,地道東北人倚评。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像馏予,于是被迫代替她去往敵國和親天梧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理霞丧,服務(wù)發(fā)現(xiàn)呢岗,斷路器,智...
    卡卡羅2017閱讀 134,714評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,318評論 25 707
  • 因為最近ios需要用到https蛹尝,所以公司的項目都從http的請求轉(zhuǎn)成了https的雙向認證后豫,這里我關(guān)于安卓端ht...
    黃海佳閱讀 5,997評論 1 21
  • 戳上方藍色字,歡迎關(guān)注噢? 夏天的時候突那,偶然在書店里看到《十角館事件》挫酿。于是買回來重讀。重讀之后有些意猶未盡愕难,于是...
    savealone閱讀 6,492評論 3 1
  • (二十七)硬漢的悲痛 在張金發(fā)的執(zhí)意追問下早龟,張二雅向爸爸坦誠而詳盡地講出了她在省城出差...
    能安大鵬閱讀 265評論 0 0