SSL原理和實現

原理:
要想保證網絡通信的安全,我們第一反應就是給傳輸的數據加密,這也是現行安全傳輸通用的模式。但在傳統加密方式(單密鑰,對稱加密)下,密鑰不可避免的要被傳送於網絡節點之間,(除非是寫死到各個節點中,不過那樣就沒有任何靈活性和普適性),在一定強度的網絡攻擊下,這種加密方式是很脆弱的。
SSL 的出現解決了這個難題,理解SSL 的關鍵是理解非對稱加密的含義。
在對稱加密的情況下,源數據A,通過使用密鑰B,加密成爲密文C。任何人,只要獲得了密鑰B,就能夠對截獲的密文C解密,還原出源數據A。(依靠"算法安全"遠不如依靠"密鑰安全");在非對稱加密中,出現了“密鑰對”的概念,即有一個公共密鑰(公鑰)和一個私有密鑰(私鑰),經公鑰加密的密文只能由私鑰解密,反過來,經私鑰加密的密文只能由公鑰解密。這是個重要的特性(數學原理可參考RSA算法),下面的模擬https通信流程說明了這一特性的重要。
1,客戶端向服務端發出請求,服務端將公鑰(以及服務端證書)響應給客戶端;
2,客戶端接收到服務器端端公鑰與證書,驗證證書是否在信任域內,不信任則結束通信,信任則使用服務端傳過來的公鑰生成一個“預備主密碼”,返回給服務端。
3,服務端接收客戶端傳過來的“預備主密碼”密文,使用私鑰解密。非對稱加密的安全性也就在於此了,第三方無法獲取到“預備主密碼”的明文,因爲除了服務端,其他任何人是沒有私鑰的。
4,雙方使用“預備主密碼”生成用於會話的“主密碼”。確認後,結束本次SSL 握手,停止使用非對稱加密。
5,雙方使用“主密碼”對稱加密傳輸數據,直到本次會話結束。
總結整個流程:先採用非對稱加密模式,保證“主密碼”只被通信雙方獲知,而後使用傳統的對稱加密方式通信,這樣,保證了密鑰安全(即“主密碼”)就等於保證了數據安全。之所以建立安全連接後,轉而使用對稱加密,是因爲非對稱加密的運算量很大,用於“常態”的數據通信十分低效。
以上描述的僅是SSL 協議中加密通信的原理,沒有涉及到證書驗證,以及客戶端,服務端模式。 

實現:
JDK裏面自帶了一個密鑰生成工具keytool,可以通過它生成SSL 通信需要的密鑰對,或者生成自簽名的證書。所有密鑰對或者簽名證書都是存放在“keystore”密鑰倉庫中,由它來管理。
下面結合具體例子說明:(java  WEB容器:tomcat 5.0)
1,生成服務端密鑰倉庫,
keytool -genkey -alias svrkey -keyalg RSA -keystore d:/svr.jks -validity 365
"alias"是生成的密鑰別名,密鑰的導入導出都需要由別名來定位。
"keystore"生成的密鑰倉庫
"validity"生成密鑰倉庫的有效期(天)
隨後會要求輸入密鑰倉庫入口密碼,比如: lostsky_11
輸完密碼後,接着會要求一系列的輸入,無非是單位,所在地區之類的信息,
但是第一項很重要!爲輸入服務端域名或IP,如: 192.168.1.3或www.591pic.com
必須與服務器域名或IP相同,否則SSL 連接無法建立(這也是SSL 通信驗證的一部分)
2,在tomcat_home/conf/server.xml中配置:
找到ssl 通信配置那一段,加入:
keystoreFile="d:/svr.jks" keystorePass="lostsky_11"
服務器啓動時會從中尋找用於建立ssl 連接的密鑰 
3,導出服務端證書
keytool -export -alias svrkey -file d:/svr.cer -keystore d:/svr.jks
"alias"爲想導出的密鑰的別名,"file"爲導出的證書,"keystore"爲存儲着導出密鑰的倉庫
4,生成客戶端密鑰倉庫 
keytool -genkey -alias clientkey -keyalg RSA -keystore d:/client.jks
會要求輸入倉庫密碼:如:midsky
5,將服務端證書導入到客戶端密鑰倉庫
keytool -import -file d:/svr.cer -keystore d:/client.jks
會要求輸入客戶端密鑰倉庫的密碼:如上是:midsky
這樣服務端的密鑰倉庫就在tomcat部署完畢了,
6,在客戶端,每次訪問服務端之前,加入
"System.setProperty("javax.net.ssl .trustStore","d://client.jks");
System.setProperty("javax.net.ssl .trustStorePassword","midsky"); " 
就把服務端證書添加到了客戶端的信任域中,能夠完成ssl 通信。
注:ssl 通信主要驗證三個方面:
a, 證書是否可信(第6步)
b, 證書是否過期(第1步:validity)
c, 證書地址是否和當前訪問地址符合(第1步)
客戶端添加信任域還有編程的動態方法,但是那樣會降低通信的安全性,對於證書相對固定的服務,不建議使用。
以上是客戶端對於服務端的驗證,這也是SSL 默認的實現方式。在這種方式下,每次通信時,發起請求方(如PC中的BROWSER)都會驗證響應方(如某個WEB服務端)的證書是否在己方信任域中,對方的證書是否過期,對方的域名或IP,是否與信任域中證書記載的一致;不符合其中任何一項,通信都會被拒絕。但反過來,響應方是不對請求方做任何驗證的。所以有些需要雙向驗證的服務(比如某些服務只能對特定的擁有證書的用戶開放),就需要添加客戶端證書,由服務端來驗證了,原理和實現與默認模式類似。

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