Java WEB HTTPS使用詳解

HTTPS通信的具體原理,這裏不做介紹。作爲一個C/S的通信協議,HTTPS是分爲Client和Server的,這裏會介紹當Tomcat WEB Server分別作爲HTTPS的客戶端和服務器端時候的配置和實現。

WEB容器作爲HTTPS的服務器端

Tomcat提供HTTPS Server的功能和瀏覽器等其他HTTPS客戶端進行交互是很常見的使用方式。Tomcat配置實現了HTTPS Server之後,瀏覽器就可以通過https協議訪問Tomcat提供的WEB服務了。

具體配置步驟如下:

生成證書

可以用java自動的工具生成證書,如果已經有可信的第三方簽發的證書或者其他工具生成的服務器證書,此步驟可以忽略,直接進行後面的步驟。

服務器證書用於後續發生SSL協商時,發給SSL Client用來驗證服務器的。在HTTPS應用場景中,默認SSL Client一般是瀏覽器,因爲瀏覽器出廠的時候會內置一些可信的第三方CA作爲驗證的CA鏈。所以此處如果使用了這些第三方CA簽發的證書作爲服務器的證書,則瀏覽器不用做任何設置就可以對服務器端進行有效的驗證。否則,因爲驗證證書需要一直到Root CA建立信任關係鏈,這裏對於自己生成的證書有兩種處理的方式:

  • 在本地建立CA,簽發服務器證書給Tomcat使用,將本地CA證書鏈導入瀏覽器作爲可信的CA,後續用來在瀏覽器端驗證Tomcat的服務器證書。

  • Tomcat的瀏覽器證書使用自簽名證書,這樣客戶端就不用再做任何配置了。

上述兩種方式在WEB開發的測試過程中使用都是沒有問題,一般用第二種方法,更簡潔一些。但是在實際的生產環境,是行不通的。

  • 方法一:因爲WEB服務面向的訪問羣體不確定,我們沒有辦法將自己生成的CA證書鏈導入到所有的瀏覽器中。

  • 方法二:自簽名證書可以協商安全的SSL通道,保證HTTP通信的通道安全,但是因爲是自簽名的,客戶端無法確認服務器端的身份,無法阻止基於中間人的釣魚***。所以最好的方式還是使用可信的第三方簽發的證書,當然這種服務是收費的。

我們下面只說明一下測試環境中證書的使用,這裏使用自簽名證書做示例:
生成證書

554


這裏使用了網上的圖片做說明,大致步驟是相同的,注意,這裏的common-name,也就是名字和姓氏那一欄需要和WEB域名一致。在實際應用過程中,瀏覽器判斷WEB Server的身份是否可行的通用做法是比較證書字段中的common-name和WEB的域名是否相同,如果不相同會提示WEB Server不可信。


導出證書

554


上一步中只是在keystore中生成了一個證書,這個keystore中可以有很多證書,這裏我們把需要的證書文件導出,導出的時候請指定別名。記下導出的證書的路徑,後面需要用到。


至此,證書的操作就已經完成了。

配置Tomcat服務器

Tomcat服務器默認提供了HTTP服務,如果需要用HTTPS服務,需要打開相應的端口,和做一些必要的配置。

700

如上圖所示,protocol中使用的是coyote方式,如果是其他的方式,如APR方式,可能配置方法會不同,具體的如果有需求,可以到網上搜索相關資料。

注意:這裏keystoreFile選擇當時生成的證書庫,keystorePass填寫自己的密碼即可。

使用HTTPS服務登錄

將配置好的tomcat服務器重啓之後,會自動加載證書庫中的證書,根據請求的域名發
送相關的證書。如圖:

554

這裏因爲用的是自簽名證書,所以提示是無效的證書認證,我們可以選擇繼續訪問,可以正常進入首頁。

WEB容器作爲HTTPS的客戶端

Tomcat因爲是WEB服務的提供者,所以作爲HTTPS的服務器端是很好理解的。但是在實際應用中WEB服務器也是很有可能作爲HTTPS的客戶端的。解決跨域訪問就是一個這樣的應用場景。考慮下面的情況:

www.A.com的網站中,需要獲取www.B.com中的某一個資源,正常的想法是,通過B提供的API直接在A的頁面中發送HTTP Get/Post請求到B的服務器中獲取,這樣是否可以呢?實際是不行的,因爲瀏覽器有同源策略,是會默認禁止在一個域中向另外一個域中直接發起請求的,如果這樣做了,會出現一個access-control-allow-origin的錯誤,這裏不仔細介紹,如果有興趣的可以搜索一下相關的內容。

我們可以看到,在瀏覽器中,直接在A的頁面中獲取B的資源是不可行的,但是實際上我們又確實有這樣的需求,怎麼辦呢?可以通過A的後臺做代理去B獲取資源,然後再將獲取的資源返回給A。這時候WEB 服務器(tomcat)就有可能作爲HTTPS的客戶端了。

準備證書

在HTTPS的使用場景中,一般只會要求對服務器進行認證,目前不會也不太可能對客戶端進行認證。所以,作爲HTTPS Client的時候,本身是不需要有證明自己身份的證書的。但是因爲要驗證服務器,所以需要有可信任的證書鏈。尋找可信任的證書鏈的具體的原則如下:

客戶端的TrustStore文件中保存着被客戶端所信任的服務器的證書信息。客戶端在進行SSL連接時,JSSE將根據這個文件中的證書決定是否信任服務器端的證書。在SunJSSE中,有一個信任管理器類負責決定是否信任遠端的證書,這個類有如下的處理規則:

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

  • 若該系統屬性沒有指定TrustStore文件,它就會去jre安裝路徑下尋找默認的TrustStore文件,這個文件的相對路徑爲:lib/security/jssecacerts。

  • 若jssecacerts不存在,但是cacerts存在(它隨J2SDK一起發行,含有數量有限的可信任的基本證書),那麼這個默認的TrustStore文件就是lib/security/cacerts。

所以我們在實際使用中,要看看具體證書放在哪裏,java1.8中,證書是放在lib/security/cacerts中的。這裏就包含了默認的一些第三方證書機構的可信的CA證書鏈。只要我們要連接的HTTPS服務器端的證書是這些第三方證書機構頒發的,則不需要做任何處理。如果服務器端沒有使用自己的CA簽發的證書或者自簽名證書怎麼辦呢?有兩個解決辦法:

  • 按照以上信任管理器的規則,將服務端的公鑰導入到jssecacerts,或者是在系統屬性中設置要加載的trustStore文件的路徑;證書導入可以用如下命令:keytool -import -file src_cer_file –keystore dest_cer_store;至於證書可以通過瀏覽器導出獲得;

  • 實現自己的證書信任管理器類,比如MyX509TrustManager,該類必須實現X509TrustManager接口中的三個method;然後在HttpsURLConnection中加載自定義的類。

第一種方法稍嫌繁瑣,第二種方法可能會更方便一些,但是有可能導致安全問題。因爲我們這裏主要是和阿里的HTTPS服務器連接,阿里用的是可信第三方CA頒發的證書,所以不存在上述說的證書無法驗證的問題。

至此,證書已經準備好了,可以進行編碼驗證了。

連接HTTPS服務器端

這部分工作比較簡單,在Java中要訪問Https鏈接時,會用到一個關鍵類HttpsURLConnection, 參見如下實現代碼:

554

創建一個URL的實例,然後打開鏈接,就可以進行一次Request操作了,通過InputStreamReader類可以獲取返回的信息。實際測試過,可以從阿里的認證服務器獲取迴應信息。具體的請求的參數和返回數據的處理可以在實際的操作過程中進行完善。


作者:Endzzz
鏈接:https://www.jianshu.com/p/e94ff6c5dcfd


作者:ibeautiful
鏈接:https://www.imooc.com/article/33745
來源:慕課網


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章