本文大部分整理自網絡,相關文章請見文後參考。html
關於證書受權中心CA以及數字證書等概念,請移步 OpenSSL 與 SSL 數字證書概念貼 ,若是你想快速自建CA而後簽發數字證書,請移步 基於OpenSSL自建CA和頒發SSL證書 。web
SSL/TLS做爲一種互聯網安全加密技術,原理較爲複雜,枯燥而無味,我也是試圖理解以後從新整理,儘可能作到層次清晰。正文開始。算法
SSL是一個介於HTTP協議與TCP之間的一個可選層,其位置大體以下:
segmentfault
SSL:(Secure Socket Layer,安全套接字層),爲Netscape所研發,用以保障在Internet上數據傳輸之安全,利用數據加密(Encryption)技術,可確保數據在網絡上之傳輸過程當中不會被截取。當前版本爲3.0。它已被普遍地用於Web瀏覽器與服務器之間的身份認證和加密數據傳輸。
SSL協議位於TCP/IP協議與各類應用層協議之間,爲數據通信提供安全支持。SSL協議可分爲兩層: SSL記錄協議(SSL Record Protocol):它創建在可靠的傳輸協議(如TCP)之上,爲高層協議提供數據封裝、壓縮、加密等基本功能的支持。 SSL握手協議(SSL Handshake Protocol):它創建在SSL記錄協議之上,用於在實際的數據傳輸開始前,通信雙方進行身份認證、協商加密算法、交換加密密鑰等。瀏覽器
TLS:(Transport Layer Security,傳輸層安全協議),用於兩個應用程序之間提供保密性和數據完整性。
TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任務組)制定的一種新的協議,它創建在SSL 3.0協議規範之上,是SSL 3.0的後續版本,能夠理解爲SSL 3.1,它是寫入了 RFC 的。該協議由兩層組成: TLS 記錄協議(TLS Record)和 TLS 握手協議(TLS Handshake)。較低的層爲 TLS 記錄協議,位於某個可靠的傳輸協議(例如 TCP)上面。安全
SSL/TLS協議提供的服務主要有:服務器
TLS的主要加強內容網絡
TLS的主要目標是使SSL更安全,並使協議的規範更精確和完善。TLS 在SSL v3.0 的基礎上,提供瞭如下加強內容:session
TLS對於安全性的改進tcp
SSL協議分爲兩部分:Handshake Protocol和Record Protocol。其中Handshake Protocol用來協商密鑰,協議的大部份內容就是通訊雙方如何利用它來安全的協商出一份密鑰。 Record Protocol則定義了傳輸的格式。
因爲非對稱加密的速度比較慢,因此它通常用於密鑰交換,雙方經過公鑰算法協商出一份密鑰,而後經過對稱加密來通訊,固然,爲了保證數據的完整性,在加密前要先通過HMAC的處理。
SSL缺省只進行server端的認證,客戶端的認證是可選的。如下是其流程圖(摘自TLS協議)。
因爲客戶端(如瀏覽器)對一些加解密算法的支持程度不同,可是在TLS協議傳輸過程當中必須使用同一套加解密算法才能保證數據可以正常的加解密。在TLS握手階段,客戶端首先要告知服務端,本身支持哪些加密算法,因此客戶端須要將本地支持的加密套件(Cipher Suite)的列表傳送給服務端。除此以外,客戶端還要產生一個隨機數,這個隨機數一方面須要在客戶端保存,另外一方面須要傳送給服務端,客戶端的隨機數須要跟服務端產生的隨機數結合起來產生後面要講到的 Master Secret 。
綜上,在這一步,客戶端主要向服務器提供如下信息:
上圖中,從Server Hello到Server Done,有些服務端的實現是每條單獨發送,有服務端實現是合併到一塊兒發送。Sever Hello和Server Done都是隻有頭沒有內容的數據。
服務端在接收到客戶端的Client Hello以後,服務端須要將本身的證書發送給客戶端。這個證書是對於服務端的一種認證。例如,客戶端收到了一個來自於稱本身是www.alipay.com的數據,可是如何證實對方是合法的alipay支付寶呢?這就是證書的做用,支付寶的證書能夠證實它是alipay,而不是財付通。證書是須要申請,並由專門的數字證書認證機構(CA)經過很是嚴格的審覈以後頒發的電子證書。頒發證書的同時會產生一個私鑰和公鑰。私鑰由服務端本身保存,不可泄漏。公鑰則是附帶在證書的信息中,能夠公開的。證書自己也附帶一個證書電子簽名,這個簽名用來驗證證書的完整性和真實性,能夠防止證書被串改。另外,證書還有個有效期。
在服務端向客戶端發送的證書中沒有提供足夠的信息(證書公鑰)的時候,還能夠向客戶端發送一個 Server Key Exchange,
此外,對於很是重要的保密數據,服務端還須要對客戶端進行驗證,以保證數據傳送給了安全的合法的客戶端。服務端能夠向客戶端發出 Cerficate Request 消息,要求客戶端發送證書對客戶端的合法性進行驗證。好比,金融機構每每只容許認證客戶連入本身的網絡,就會向正式客戶提供USB密鑰,裏面就包含了一張客戶端證書。
跟客戶端同樣,服務端也須要產生一個隨機數發送給客戶端。客戶端和服務端都須要使用這兩個隨機數來產生Master Secret。
最後服務端會發送一個Server Hello Done消息給客戶端,表示Server Hello消息結束了。
綜上,在這一步,服務器的迴應包含如下內容:
Client Key Exchange
若是服務端須要對客戶端進行驗證,在客戶端收到服務端的 Server Hello 消息以後,首先須要向服務端發送客戶端的證書,讓服務端來驗證客戶端的合法性。
Certificate Verify
接着,客戶端須要對服務端的證書進行檢查,若是證書不是可信機構頒佈、或者證書中的域名與實際域名不一致、或者證書已通過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通訊。若是證書沒有問題,客戶端就會從服務器證書中取出服務器的公鑰。而後,向服務器發送下面三項信息:
上面第一項的隨機數,是整個握手階段出現的第三個隨機數,它是客戶端使用一些加密算法(例如:RSA, Diffie-Hellman)產生一個48個字節的Key,這個Key叫 PreMaster Secret,不少材料上也被稱做 PreMaster Key。
ChangeCipherSpec
ChangeCipherSpec是一個獨立的協議,體如今數據包中就是一個字節的數據,用於告知服務端,客戶端已經切換到以前協商好的加密套件(Cipher Suite)的狀態,準備使用以前協商好的加密套件加密數據並傳輸了。
在ChangecipherSpec傳輸完畢以後,客戶端會使用以前協商好的加密套件和Session Secret加密一段 Finish 的數據傳送給服務端,此數據是爲了在正式傳輸應用數據以前對剛剛握手創建起來的加解密通道進行驗證。
服務端在接收到客戶端傳過來的 PreMaster 加密數據以後,使用私鑰對這段加密數據進行解密,並對數據進行驗證,也會使用跟客戶端一樣的方式生成 Session Secret,一切準備好以後,會給客戶端發送一個 ChangeCipherSpec,告知客戶端已經切換到協商過的加密套件狀態,準備使用加密套件和 Session Secret加密數據了。以後,服務端也會使用 Session Secret 加密一段 Finish 消息發送給客戶端,以驗證以前經過握手創建起來的加解密通道是否成功。
根據以前的握手信息,若是客戶端和服務端都能對Finish信息進行正常加解密且消息正確的被驗證,則說明握手通道已經創建成功,接下來,雙方可使用上面產生的Session Secret對數據進行加密傳輸了。
Secret Keys
上面的分析和講解主要是爲了突出握手的過程,因此PreMaster secret,Master secret,session secret都是一代而過,可是對於Https,SSL/TLS深刻的理解和掌握,這些Secret Keys是很是重要的部分。因此,準備把這些Secret Keys抽出來單獨分析和講解。
咱們先來看看這些Secret Keys的生成過程以及做用流程圖:
PreMaster secret
PreMaster Secret是在客戶端使用RSA或者Diffie-Hellman等加密算法生成的。它將用來跟服務端和客戶端在Hello階段產生的隨機數結合在一塊兒生成 Master Secret。在客戶端使用服務端的公鑰對PreMaster Secret進行加密以後傳送給服務端,服務端將使用私鑰進行解密獲得PreMaster secret。也就是說服務端和客戶端都有一份相同的PreMaster secret和隨機數。
PreMaster secret前兩個字節是TLS的版本號,這是一個比較重要的用來覈對握手數據的版本號,由於在Client Hello階段,客戶端會發送一份加密套件列表和當前支持的SSL/TLS的版本號給服務端,並且是使用明文傳送的,若是握手的數據包被破解以後,攻擊者頗有可能串改數據包,選擇一個安全性較低的加密套件和版本給服務端,從而對數據進行破解。因此,服務端須要對密文中解密出來對的PreMaster版本號跟以前Client Hello階段的版本號進行對比,若是版本號變低,則說明被串改,則當即中止發送任何消息。
關於PreMaster Secret(Key)的計算請參考 Https SSL/TLS PreMaster/Master Secret(Key)計算。
Master secret
上面已經提到,因爲服務端和客戶端都有一份相同的PreMaster secret和隨機數,這個隨機數將做爲後面產生Master secret的種子,結合PreMaster secret,客戶端和服務端將計算出一樣的Master secret。
Master secret是有系列的hash值組成的,它將做爲數據加解密相關的secret的 Key Material 的一部分。Key Material最終解析出來的數據以下:
其中,write MAC key,就是session secret或者說是session key。Client write MAC key是客戶端發數據的session secret,Server write MAC secret是服務端發送數據的session key。MAC(Message Authentication Code),是一個數字簽名,用來驗證數據的完整性,能夠檢測到數據是否被串改。
關於Session Secret(Key)的計算請參考 Https SSL/TLS Session Secret(Key)計算。
在全部的握手階段都完成以後,就能夠開始傳送應用數據了。應用數據在傳輸以前,首先要附加上MAC secret,而後再對這個數據包使用write encryption key進行加密。在服務端收到密文以後,使用Client write encryption key進行解密,客戶端收到服務端的數據以後使用Server write encryption key進行解密,而後使用各自的write MAC key對數據的完整性包括是否被串改進行驗證。
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的公鑰的真實性)
(產生一份祕密消息,這份祕密消息處理後將用做加密密鑰,加密初始化向量(IV)和hmac的密鑰。將這份祕密消息-協議中稱爲per_master_secret-用B的公鑰加密,封裝成稱做ClientKeyExchange的消息。因爲用了B的公鑰,保證了第三方沒法竊聽)
我生成了一份祕密消息,並用你的公鑰加密了,給你(把ClientKeyExchange發給B)
注意,下面我就要用加密的辦法給你發消息了!
(將祕密消息進行處理,生成加密密鑰,加密初始化向量和hmac的密鑰)
[我說完了]
B:(用本身的私鑰將ClientKeyExchange中的祕密消息解密出來,而後將祕密消息進行處理,生成加密密鑰,加密初始化向量和hmac的密鑰,這時雙方已經安全的協商出一套加密辦法了)
注意,我也要開始用加密的辦法給你發消息了!
[我說完了]
A: [個人祕密是...]
B: [其它人不會聽到的...]
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通訊的消息,並可攔截,替換和添加這些消息。
下面探討一下SSL的代理是怎樣工做的
當在瀏覽器裏設置了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攻擊的好場所,見上面的安所有分)。
CA證書以及如何使用OpenSSL自簽署,見文章OpenSSL自簽署證書 。