傳輸層安全-認識SSL

如果覺得這篇文章對您有所幫助,在觀看完文章之餘,希望能點選下方方廣告,當作是對YOGO的支持,讓YOGO更有寫作的動力。

一、 前 言

首先要澄清一下名字的混淆 ,SSL(Secure Socket Layer) 是netscape公司設計的,主要用於web的安全傳輸協定。這種協定在WEB上獲得了廣泛的應用。

二、SSL運作原理(簡述)

1.Client透過HTTPS連到Server。
2.Server傳送Server Public Key給client。
3.Client產生後續傳輸資料需要用來加密/解密用的Session Key,並以Server傳過來的Public Key加密後回傳給Server。
4.Server用Private Key解開Client以Public Key加密回傳的資料,以取得Session Key。
5.後續Client與Server間傳送資料就以此Session Key來做資料加密與解密的處理,處理的時間會比使用Server的Public Key與Private Key要快速許多。

三、整體結構概覽

以下簡要介紹SSL協議的工作方式。客戶端要收發幾個握手信號:

發送一個ClientHello消息,說明它支持的密碼演算法列表、壓縮方法及最高協議版本,也發送稍後將被使用的隨機數。

然後收到一個ServerHello消息,包含伺服器選擇的連接參數,源自客戶端初期所提供的ClientHello。

當雙方知道了連接參數,客戶端與伺服器交換證書(依靠被選擇的公鑰系統)。這些證書通常基於X.509,不過已有草案支持以OpenPGP為基礎的證書。

伺服器請求客戶端公鑰。客戶端有證書即雙向身份認證,沒證書時隨機生成公鑰。

客戶端與伺服器通過公鑰保密協商共同的主私鑰(雙方隨機協商),這通過精心謹慎設計的偽隨機數功能實現。結果可能使用Diffie-Hellman交換,或簡化的公鑰加密,雙方各自用私鑰解密。所有其他關鍵數據的加密均使用這個「主密鑰」。

數據傳輸中記錄層(Record layer)用於封裝更高層的HTTP等協議。記錄層數據可以被隨意壓縮、加密,與消息驗證碼壓縮在一起。每個記錄層包都有一個Content-Type段用以記錄更上層用的協議。



SSL是一個介於HTTP協議與TCP之間的一個可選層,其位置大致如下:
- - - - - - - - -
HTTP
- - - - - - - - -
SSL
- - - - - - - - -
TCP
- - - - - - - - -
IP
- - - - - - - - -

如果利用SSL協議來訪問網頁,其步驟如下:

用戶:在瀏覽器的地址欄裡輸入https://www.sslserver.com/
HTTP層:將用戶需求翻譯成HTTP請求,如
GET /index.htm HTTP/1.1
Host www.sslserver.com
SSL層: 借助下層協議的的信道安全的協商出一份加密密鑰,並用此密鑰來加密HTTP請求。
TCP層:與web server的443端口建立連接,傳遞SSL處理後的數據。
接收端與此過程相反。
SSL在TCP之上建立了一個加密通道,通過這一層的數據經過了加密,因此達到保密的效果。
SSL協議分為兩部分:Handshake Protocol和Record Protocol。
Handshake Protocol用來協商密鑰,協議的大部分內容就是通信雙方如何利用它來安全的協商出一份密鑰。
Record Protocol則定義了傳輸的格式。

常用演算法選擇

公鑰密碼系統:RSA、Diffie-Hellman、DSA及Fortezza
對稱密鑰系統:RC2、RC4、IDEA、DES、Triple DES及AES
單向散列函數:MD5及SHA

密鑰協商過程

由於非對稱加密的速度比較慢,所以它一般用於密鑰交換,雙方通過公鑰算法協商出一份密鑰,然後通過對稱加密來通信,當然,為了保證數據的完整性,在加密前要先經過HMAC的處理。

SSL缺省只進行server端的認證,客戶端的認證是可選的。以下是其流程圖(摘自TLS協議)。

Client Server
ClientHello ->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
ServerHelloDone
<-
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished ->
[ChangeCipherSpec]
<- Finished
Application Data <-> Application Data

簡單的說便是:SSL客戶端(也是TCP的客戶端)在TCP鏈接建立之後,發出一個ClientHello來發起握手,這個消息裡面包含了自己可實現的算法列表和其它一些需要的消息,SSL的服務器端會回應一個ServerHello,這裡面確定了這次通信所需要的算法,然後發過去自己的證書(裡面包含了身份和自己的公鑰)。Client在收到這個消息後會生成一個秘密消息,用SSL服務器的公鑰加密後傳過去,SSL服務器端用自己的私鑰解密後,會話密鑰協商成功,雙方可以用同一份會話密鑰來通信了。

密鑰協商的形象化比喻

如果上面的說明不夠清晰,這裡用個形象的比喻,我們假設A與B通信,A是SSL客戶端,B是SSL伺服器端,加密後的消息放在方括號[]裡,以突出明文消息的區別。雙方的處理動作的說明用圓括號()括起。

A:我想和你安全的通話,我這裡的對稱加密算法有DES,RC5,密鑰交換算法有RSA和DH,摘要算法有MD5和SHA。

B:我們用DES-RSA-SHA這對組合好了。

這是我的證書,裡面有我的名字和公鑰,你拿去驗證一下我的身份(把證書發給A)。

目前沒有別的可說的了。

A:(查看證書上B的名字是否無誤,並通過手頭早已有的CA的證書驗證了B的證書的真實性,如果其中一項有誤,發出警告並斷開連接,這一步保證了B的公鑰的真實性)

(產生一份秘密消息,這份秘密消息處理後將用作加密密鑰,加密初始化向量和hmac的密鑰。將這份秘密消息-協議中稱為per_master_secret-用B的公鑰加密,封裝成稱作ClientKeyExchange的消息。由於用了B的公鑰,保證了第三方無法竊聽)

我生成了一份秘密消息,並用你的公鑰加密了,給你(把ClientKeyExchange發給B)

注意,下面我就要用加密的辦法給你發消息了!

(將秘密消息進行處理,生成加密密鑰,加密初始化向量和hmac的密鑰)

[我說完了]

B:(用自己的私鑰將ClientKeyExchange中的秘密消息解密出來,然後將秘密消息進行處理,生成加密密鑰,加密初始化向量和hmac的密鑰,這時雙方已經安全的協商出一套加密辦法了)

注意,我也要開始用加密的辦法給你發消息了!

[我說完了]

A: [我的秘密是...]

B: [其它人不會聽到的...]

加密的計算

上一步講了密鑰的協商,但是還沒有闡明是如何利用加密密鑰,加密初始化向量和hmac的密鑰來加密消息的,其實其過程不過如此:

1 借助hmac的密鑰,對明文的消息做安全的摘要處理,然後和明文放到一起。
2 借助加密密鑰,加密初始化向量加密上面的消息。

安全性

SecurityPortal在2000年底有一份文章《The End of SSL and SSH?》激起了很多的討論, 目前也有一些成熟的工具如dsniff(http://www.monkey.org/~dugsong/dsniff/)可以通過man in the middle攻擊來截獲https的消息。

從上面的原理可知,SSL的結構是嚴謹的,問題一般出現在實際不嚴謹的應用中。常見的攻擊就是middle in the middle攻擊,它是指在A和B通信的同時,有第三方C處於信道的中間,可以完全聽到A與B通信的消息,並可攔截,替換和添加這些消息。

1.SSL可以允許多種密鑰交換算法,而有些算法,如DH,沒有證書的概念,這樣A便無法驗證B的公鑰和身份的真實性,從而C可以輕易的冒充,用自己的密鑰與雙方通信,從而竊聽到別人談話的內容。

而為了防止middle in the middle攻擊,應該採用有證書的密鑰交換算法。

2.有了證書以後,如果C用自己的證書替換掉原有的證書之後,A的瀏覽器會彈出一個警告框進行警告,但又有多少人會注意這個警告呢?

3 由於美國密碼出口的限制,IE,netscape等瀏覽器所支持的加密強度是很弱的,如果只採用瀏覽器自帶的加密功能的話,理論上存在被破解可能。

代理(Proxy)

下面探討一下SSL的代理是怎樣工作的(可參見[6])。這可能與你開始想的不太一樣:)

當在瀏覽器裡設置了https的代理,而且在瀏覽器裡輸入了https://www.example.com/之後,瀏覽器會與proxy建立tcp鏈接,然後向其發出這麼一段消息:

CONNECT server.example.com:443 HTTP/1.1
Host: server.example.com:443

然後proxy會向webserver端建立tcp連接,之後,這個代理便完全成了個內容轉發裝置。瀏覽器與web server會建立一個安全通道,因此這個安全通道是端到端的,儘管所有的信息流過了proxy,但其內容proxy是無法解密和改動的(當然要由證書的支持,否則這個地方便是個man in the middle攻擊的好場所,見上面的討論)。



關於證書

注意,如果對於一般的應用,管理員只需生成「證書請求」(後綴大多為.csr),它包含你的名字和公鑰,然後把這份請求交給諸如verisign等有CA服務公司(當然,連同幾百美金),你的證書請求經驗證後,CA用它的私鑰簽名,形成正式的證書發還給你。管理員再在web server上導入這個證書就行了。如果你不想花那筆錢,或者想瞭解一下原理,可以自己做CA。從ca的角度講,你需要CA的私鑰和公鑰。從想要證書的服務器角度將,需要把服務器的證書請求交給CA.
如果你要自己做CA,別忘了客戶端需要導入CA的證書(CA的證書是自簽名的,導入它意味著你「信任」這個CA簽署的證書)。而商業CA的一般不用,因為它們已經內置在你的瀏覽器中了。

三、使用SSL可能會遇到的問題

1.Server的Private Key若不小心流出去,那有心人士只要在SSL連線開始前就開始監聽Client的封包,就可以取得Session Key,這意味著後續傳輸的資料等於是以明文傳送,這會相當危險。

2.若Client端電腦被植入木馬,Session Key被取得,那以後只要攔截加密的封包就可以直接解開取得資料。

 
四、為什麼要付錢像公正第三者如VeriSign購買憑證

因為瀏覽器預先就會埋入這些公司憑證的相關資料,所以只要使用HTTPS連上使用這些公司簽署憑證的網站,就可以直接建立SSL連線,不會出現任何警告訊息,而且可以比對憑證上面的資訊是否與網站相符,這會讓人安心得多。

自己製造憑證,雖然一樣會有SSL加密的效果,但只要一使用HTTPS連上線,就會出現警告視窗,而且憑證所示的資料並不一定會與網站相同,這也會讓人懷疑是不是連上了釣魚網站。
 

參考資料:
認識SSL:http://forum.liferec.com/viewtopic.php?t=411
安全性-3.SSL安全套階層原:http://fey.feyyo.idv.tw/lifetype/index.php?op=ViewArticle&articleId=330&blogId=1&searchTerms=%73%73%6c%20
傳輸層安全:http://zh.wikipedia.org/zh-tw/SSL

 

留言

這個網誌中的熱門文章

用PHP寄MAIL的方法

ImageMagick應用大全(一)

php安裝openssl的方法