java | HttpsURLConnection 實(shí)現(xiàn)https請求

轉(zhuǎn)載一篇關(guān)于實(shí)現(xiàn)https請求的博文阶剑,寫的非常詳盡跃巡,原文出處:http://www.blogjava.net/etlan/archive/2006/06/29/55767.html

摘 要

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

引言

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

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

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

JSSE簡介

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è)開放的標(biāo)準(zhǔn)易结,不只是Sun公司才能實(shí)現(xiàn)一個(gè)JSSE,事實(shí)上其他公司有自己實(shí)現(xiàn)的JSSE搞动。

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

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

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

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

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

直接使用類HttpsURLConnection訪問Web頁面

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

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

/*下面這段代碼實(shí)現(xiàn)向Web頁面發(fā)送數(shù)據(jù),實(shí)現(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時(shí),程序?qū)伋霎惓?a target="_blank" rel="nofollow">javax.net.ssl.SSLException产弹,這是由于https://login.bjut.edu.cn站點(diǎn)的安全證書不被JSSE所信任。根據(jù)JSSE簡介中對信任管理器的分析痰哨,一種解決這個(gè)問題的方法是按照信任管理器的處理規(guī)則,把站點(diǎn)的證書放到證書庫文件jssecacerts中斤斧,或者把證書存放到任一TrustStore文件中,然后設(shè)置系統(tǒng)屬性javax.net.sll.trustStore指向該文件撬讽。另一種解決方法則是自己實(shí)現(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為目標(biāo)TrustStore文件。

在使用keytool之前靡挥,首先要取得源證書文件,這個(gè)源文件可使用IE瀏覽器獲得跋破,IE瀏覽器會(huì)把訪問過的HTTPS站點(diǎn)的證書保存到本地。從IE瀏覽器導(dǎo)出證書的方法是打開“Internet 選項(xiàng)”瓶蝴,選擇“內(nèi)容”選項(xiàng)卡,點(diǎn)擊“證書…”按鈕舷手,在打開的證書對話框中,選中一個(gè)證書男窟,然后點(diǎn)擊“導(dǎo)出…”按鈕,按提示一步步將該證書保存到一文件中歉眷。最后就可利用keytool把該證書導(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信任該證書台囱,從而使程序可以訪問使用未經(jīng)驗(yàn)證的證書的HTTPS站點(diǎn)。

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

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

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

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

該方法檢查客戶端的證書睹耐,若不信任該證書則拋出異常蒸眠。由于我們不需要對客戶端進(jìn)行認(rèn)證前翎,因此我們只需要執(zhí)行默認(rèn)的信任管理器的這個(gè)方法勺拣。JSSE中药有,默認(rèn)的信任管理器類為TrustManager。

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

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

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

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

假設(shè)自己實(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)威機(jī)構(gòu)的驗(yàn)證,只要實(shí)現(xiàn)了接口X509TrustManager的類MyX509TrustManager信任該證書篡撵。

小結(jié)

本文主要介紹了在HTTPS的證書未經(jīng)權(quán)威機(jī)構(gòu)認(rèn)證的情況下,訪問HTTPS站點(diǎn)的兩種方法育谬,一種方法是把該證書導(dǎo)入到Java的TrustStore文件中,另一種是自己實(shí)現(xiàn)并覆蓋JSSE缺省的證書信任管理器類膛檀。兩種方法各有優(yōu)缺點(diǎn),第一種方法不會(huì)影響JSSE的安全性咖刃,但需要手工導(dǎo)入證書;第二種方法雖然不用手工導(dǎo)入證書嚎杨,但需要小心使用,否則會(huì)帶來一些安全隱患磕潮。摘 要 JSSE是一個(gè)SSL和TLS的純Java實(shí)現(xiàn),通過JSSE可以很容易地編程實(shí)現(xiàn)對HTTPS站點(diǎn)的訪問自脯。但是,如果該站點(diǎn)的證書未經(jīng)權(quán)威機(jī)構(gòu)的驗(yàn)證膏潮,JSSE將拒絕信任該證書從而不能訪問HTTPS站點(diǎn)。本文在簡要介紹JSSE的基礎(chǔ)上提出了兩種解決該問題的方法。


(完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末油额,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子刻帚,更是在濱河造成了極大的恐慌,老刑警劉巖崇众,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異顷歌,居然都是意外死亡锰蓬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門芹扭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冯勉,你說我怎么就攤上這事∽普” “怎么了浮禾?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盈电。 經(jīng)常有香客問我,道長匆帚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任互拾,我火速辦了婚禮,結(jié)果婚禮上嚎幸,老公的妹妹穿的比我還像新娘。我一直安慰自己嫉晶,他們只是感情好田篇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布泊柬。 她就那樣靜靜地躺著,像睡著了一般兽赁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天剪况,我揣著相機(jī)與錄音,去河邊找鬼译断。 笑死,一個(gè)胖子當(dāng)著我的面吹牛孙咪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翎蹈,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼合陵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拥知,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎低剔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體襟齿,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡枕赵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了烁设。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钓试。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡副瀑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出糠睡,到底是詐尸還是另有隱情,我是刑警寧澤狈孔,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站均抽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏油挥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一攘乒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惋鹅,春花似錦、人聲如沸闰集。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至洞坑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迟杂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工排拷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人监氢。 一個(gè)月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓藤违,卻偏偏與公主長得像纵揍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子泽谨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)吧雹,斷路器,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,777評論 25 707
  • 從三月份找實(shí)習(xí)到現(xiàn)在雄卷,面了一些公司,掛了不少龙亲,但最終還是拿到小米悍抑、百度鳄炉、阿里搜骡、京東、新浪记靡、CVTE谈竿、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,213評論 11 349
  • “所謂美人者空凸,以花為貌,以鳥為聲呀洲,以月為神,以柳為態(tài)啼止,以玉為骨,以冰雪為膚献烦,以秋水為姿滓窍,以詩詞為心巩那,吾無間然矣此蜈〗跻啵”...
    梅琛閱讀 275評論 0 1