SSL + WS-Security = Web Service安全保障

(原文地址:http://cenwenchu.iteye.com/blog/316729)

今天早晨看了一下blog的留言,發現有位朋友給我留了言,提到了他正在研究SCA,同時也有些困惑,當在異構分佈式環境的情況下,不論是否使用SCA規範來實現,都採用Web Service來完成面向服務的服務調用,覺得SCA沒有什麼優勢可言。其實這是一個誤解,SCA框架規範並不是一個具體的業務場景解決實施規範,它是一種框架結構性規範,它的精華部分主要在於:一.將抽象和封裝由對象提升到了業務組件模塊 二.框架的可擴展性(也就是因爲沒有實現的約束,纔會能夠易於擴展)。當然這兩點所帶來的好處那就是在這麼一個精煉的框架核心規範下,不斷融入了外界的各種好的技術和理念,就好比現在的Web2.0最重要的一點特質,規範的只是接口(用於統一交互的管理),開放的是接口下的任何貢獻,主動參與和主動的集成將會使得框架越來越有活力,Spring就是很好的例子。而SCA和Spring的差異我也早在前面的文章中說過,SCA和其他的規範一樣,並不是一個橫空出世的規範,是積累在過去的失敗中沉積的產物。最後打了個比方,SCA規範好比一本菜譜,至於採用什麼鍋子,用哪裏產的材料都是由廚師自己掌握,這也是架構師和程序員需要共同努力將這個規範實踐的原動力,正確的做事和做正確的事是成敗的兩個關鍵。言歸正傳,繼續這次的主題。

在前面的服務框架工作中,對於Web Service的支持成爲了這段時間的重點工作,從開始的壓力測試,Java客戶端的兼容性測試到.net,php客戶端的兼容性測試,WS-Security的集成,服務框架對於Web Service的支持在需求中逐漸增強。AEP第一期基本完成準備上線,第二期的需求也已經在醞釀中,ASF的第二期功能需求也逐漸的被提出來了,有一點看上去優先級比較高,因此我就開始動手先做,那就是SSL。一開始的時候對於SSL需求有些誤解,以爲是要做Web 服務器端的SSL,其實我們需要做的是硬件的SSL,只不過“首架”的意思是需要對SSL模式下的客戶端調用作準備(的確,客戶端在SSL不論是硬件還是軟件模式下都需要作一定的工作)。後續將講述一下我在做Web 服務器端SSL平臺集成的工作和SA專家交流了解的硬件SSL的架構策略。

What is SSL

雖然以前也對SSL有所聞,也常看到IE突然蹦出一個安全提示框,但是對於SSL的具體原理以及結構沒有仔細看過。既然要用了,還是那個原則,先把原理搞清楚,然後再去實踐。

SSL(Secure Socket Layer)是一種通信交互協議,由Netscape公司在1994年制定,主要目的就是確保在web 服務器和瀏覽器之間數據傳輸安全。SSL協議層是在TCP/IP層和應用層之間。當前TLS(Transport Layer Security)正在逐漸替代SSL(最新版本v3)。

SSL協議分成以下幾部分:

Record Protocal是SSL的基礎層,SSL所有的上層操作都是基於這個層次,這層主要負責消息內容的分段,壓縮,加密和數字摘要等操作。

Handshake Protocal故名思義就是握手協議,也是在正式應用數據傳輸前雙方交換加密設置以及認證的流程規範協議。

Change Cipher Spec Protocol是基於record協議層通知遠端服務器修改record協議層中安全設置的協議。

Alert Protocol是基於record協議發送警告到遠端服務器的協議。

SSL的具體流程圖:

SSL的流程也體現了對於對稱性密鑰和非對稱性密鑰的使用,由於對稱性密鑰加密比非對稱性密鑰加密要快1000倍,那麼對稱性密鑰被用來做對內容的加密,而非對稱性密鑰用來做傳遞對稱性密鑰的加密手段。

服務端所需要具備的是一個擁有服務端的標示,公鑰私鑰對的證書。在握手的流程中,服務端將帶有公鑰的證書抽取出來發送給客戶端,客戶端就首先可以判斷證書頒發者是否屬於本機受信的CA,如果不是,就會類似於IE跳出提示,如果通過了這部分CA認證,雙方就可以通過非對稱性加密算法來交換客戶端生成的臨時對稱密碼,進行安全加密信息交互。

軟件SSL的實踐

因爲當前所有的單元測試都是通過我提供的ASF模板類,所以啓動的Web Service都是服務框架中Jetty發佈的Web Service,很輕量級,沒有以往測試Web應用的複雜,不需要單獨去啓動一個Web Container。前期對於WS-Security的集成已經使得單元測試可以支持帶WS-Security的Web Service的測試。

抱着試一試的心理,直接用服務框架發佈了SSL的Web Service,客戶端調用了一下,沒有成功,但是錯誤還不能定位是客戶端還是服務端的問題,因此首先去外部配置了Tomcat來建立了一個SSL服務端。

Tomcat SSL服務端的配置:(只需要修改一個文件conf/server.xml)

 

maxThreads="150" minSpareThreads="25" maxSpareThreads="75"

enableLookups="false" disableUploadTimeout="true"

acceptCount="100" scheme="https" secure="true"

clientAuth="false" sslProtocol="TLS" keystoreFile="D:/work/asf/webservice/src/conf.test/keys/alisoft.jks"

keystorePass="alisoft" keystoreType="jks" truststoreFile="D:/work/asf/webservice/src/conf.test/keys/alisoft.jks"

truststorePass="alisoft" truststoreType="jks"/>

clientAuth沒有必要配置成爲true,不需要重複反向再認證。如果這個值設爲false。其他幾個值就是生成的服務端證書庫位置及密碼。這裏所要注意的就是要求keystore密碼和私鑰密碼一樣,因爲只有一個配置密碼的地方,這在生成公鑰密鑰對時兩者密碼寫成一致。這樣就OK了,直接訪問8443端口就能作爲https來訪問服務了。

採用XFire客戶端來做單元測試,代碼如下:

public static void SSLSecurityTest()

{

Service serviceModel = new ObjectServiceFactory().create(IAccountService.class);

//https的客戶端代碼需要增加的

System.setProperty ( "java.protocol.handler.pkgs" , "com.sun.net.ssl.internal.www.protocol" );

System.setProperty ( "javax.net.ssl.keyStore" , "D:/work/asf/webservice/src/conf.test/keys/myisvdemo.jks" );

System.setProperty ( "javax.net.ssl.keyStorePassword" , "myisvdemo" );

System.setProperty ( "javax.net.ssl.trustStore" , "D:/work/asf/webservice/src/conf.test/keys/myisvdemo.jks" );

System.setProperty ( "javax.net.ssl.trustStorePassword" , "myisvdemo" );

System.setProperty ("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");

Security.addProvider ( new com.sun.net.ssl.internal.ssl.Provider());

String serviceUrl = "http://localhost:8080/axis2/services/AccountService";

String serviceHttpsUrl = "https://localhost:8443/xfire/services/AccountService";

String serviceHttpsUrl2 = "https://localhost:8443/axis2/services/AccountService";

try

{

IAccountService service = (IAccountService)serviceFactory.create(serviceModel,serviceHttpsUrl2);

//WS-Security所需要的配置

Client client = ((XFireProxy)Proxy.getInvocationHandler(service)).getClient();

client.addOutHandler(new DOMOutHandler());

Properties properties = new Properties();

properties.setProperty(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "false");

properties.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE);

//properties.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP);

properties.setProperty(WSHandlerConstants.SIG_PROP_FILE, "keys/client.properties");

//properties.setProperty(WSHandlerConstants.USER, "myisvdemo");

properties.setProperty(WSHandlerConstants.USER, "wenchu");

properties.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, ClientUtPasswordHander.class.getName());

//properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "IssuerSerial");//"DirectReference","IssuerSerial","SKIKeyIdentifier"

properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "SKIKeyIdentifier");

client.addOutHandler(new WSS4JOutHandler(properties));

AccountBean[] result = service.getUserAccountList("te", "ta");

System.out.println(result.length);

}

catch(Exception ex){ex.printStackTrace();}

}

這樣保證了客戶端的配置已經沒有問題了,因此就主要將ASF框架中的SSL集成進去。由於ASF中集成的是Jetty,因此只需要在Jetty動態建立Mapping Server的時候,Server的connector爲以SslSocketConnector類型來構造,這樣就可以響應https的部分了,同時也可以在其它端口發佈成爲不需要SSL的服務。這裏細節就略去了,改造不是很複雜,只需要對Jetty較爲了解即可。不過這裏還是要贊一下Jetty,真是輕量級的好東西啊。集成以後再次作單元測試,OK,測試通過。

.Net的客戶端測試

最後就需要對.net所SSL的測試,由於.net客戶端已經在上次配置了policy作爲WS-Security的配置,按照常理來說應該不需要再配置證書之類的東西了,就嘗試着做了一下,在建立Web Reference的時候會有提示說證書授權的認證不符合要訪問的地址的身份,這個可以忽略。然後接下去測試了一下,就總是提示無法建立TLS/SSL的交互通道,查了一下,只需要加入下面一句話即可:

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

它的作用就是接受所有的證書,也就是在我們SSL中的流程中,檢查證書CA是否受信這部分省略,就好比我們訪問一些非受信證書的網站跳出的提示框我們點擊確認一樣。

到此爲止,應用服務器的SSL配置和測試就基本結束了。後面要談到的就是硬件SSL的結構和設計。

硬件SSL結構設計

首先爲什麼要使用SSL來加密呢,乾脆用WS-Security就好了,而且WS-Security有着很多SSL所無法做到的特性(不基於傳輸層,保障非點對點的安全傳輸,部分加密等等)。但是在前面的壓力測試中明顯可以看到還沒有用到加密,僅僅是簽名服務器的CPU消耗就成倍的增長,可見對於性能的影響。同時上面提到的應用服務器SSL,其實也是類似於WS-Security,消耗比較大。因此就提出了硬件SSL的設計。

這裏主要提了兩種,第二種也是現在SA比較推薦的。

一. 爲應用服務器增加獨立的SSL加速卡,例如roadcom CryptoNetXM卡,SSL加速卡的作用在於能夠將應用服務器處理SSL的工作獨立完成,讓應用服務器專心處理應用請求,使得應用服務器性能不受影響。

圖 SSL加速卡部署圖

由於許多服務器使用的是不同的加密數據,因此管理這樣一個Web服務器組會花費比較大並且複雜。同時傳統的負載均衡陣列中每一個處理加密服務器要求有一個SSL加速卡和數字證書,而證書是被CA簽署過的一個電子認證標識,在加密通信方面提供了一致性的驗證,這樣對於CA的電子認證標識管理也是很複雜的一件事,因此產生了第二種設計模式。

二. 將SSL基礎結構與BIG-IP結合

BIG-IP是一個運行有BIG-IP負載均衡軟件的服務器,它通過SSL加速卡實現了SSL的off-loading,同時還可以實現應用層和IP層的負載均衡。通過SSL終結,前端的BIG-IP負責SSL的集中處理以及同時將處理後的請求負載均衡到各個應用服務器上,這樣既降低了SSL證書管理成本,也減少了Web服務器組的管理複雜性。

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