來自:Weizhao的博客算法
在上已一節中介紹了兩種加密方法瀏覽器
其中對稱加密性能高,可是有泄露密鑰的風險,而非對稱加密相反,加密性能較差,可是密鑰不易泄露,那麼能不能把他們進行一下結合呢?安全
HTTPS經由HTTP進行通訊,但利用SSL/TLS來加密數據包,而SSL/TLS的加密方式就是採用了對稱加密與非對稱加密的結合。服務器
SSL/TLS考慮到非對稱加密的性能較低,因此在初始協商對稱加密密鑰時,使用了非對稱加密,當對稱加密密鑰協商完成後,則後續全部的通信,所有采用對稱加密進行通信。 dom
可是這種方式也有一些問題,以下沒法證實公開密鑰就是真實服務器的公開密鑰性能
好比與B服務器進行通訊,怎麼確認公開密鑰是B服務器的,後續在公開密鑰傳輸途中已經被替換了,可是卻發現不了。加密
因爲任何人均可以訪問服務器,因此不可能一一把公鑰告訴他們,那麼能不能提供一個公鑰下載的地方讓客戶機訪問服務器時先下載公鑰,可是下載公鑰的地址也有多是假的,不可取。3d
那麼有沒有更好的方式,既能安全的獲取公鑰又能確保訪問的服務器是真實的?答案:由數字證書認證機構頒發(CA)公開密鑰證書cdn
數字證書認證機構是客戶端和服務器端均可以信賴的第三方機構,VeriSign就是一家數字證書機構。流程以下:blog
這裏應該有人好奇,證書籤發機構的公鑰是怎麼傳到客戶端的?瀏覽器在發佈時,已經包含了主流的認證的機構的公開密鑰了,因此是不須要傳輸的。
上圖大體描述了 SSL/TLS 的握手過程,具體細節以下:
握手第一步是客戶端向服務端發送 Client Hello 消息,這個消息裏包含了一個客戶端生成的隨機數 Random一、客戶端支持的加密套件(Support Ciphers)和 SSL Version 等信息。經過 Wireshark 抓包,咱們能夠看到以下信息:
第二步是服務端向客戶端發送 Server Hello 消息,這個消息會從 Client Hello 傳過來的 Support Ciphers 裏肯定一份加密套件,這個套件決定了後續加密和生成摘要時具體使用哪些算法,另外還會生成一份隨機數 Random2。注意,至此客戶端和服務端都擁有了兩個隨機數(Random1+ Random2),這兩個隨機數會在後續生成對稱祕鑰時用到。
這一步是服務端將本身的證書下發給客戶端,讓客戶端驗證本身的身份,客戶端驗證經過後取出證書中的公鑰。
Server Hello Done 通知客戶端 Server Hello 過程結束。
客戶端收到服務端傳來的證書後,先從 CA 驗證該證書的合法性,驗證經過後取出證書中的服務端公鑰,再生成一個隨機數 Random3,再用服務端公鑰非對稱加密 Random3生成 PreMaster Key。
Client Key Exchange 就是將這個 key 傳給服務端,服務端再用本身的私鑰解出這個 PreMaster Key 獲得客戶端生成的 Random3。至此,客戶端和服務端都擁有 Random1 + Random2 + Random3,兩邊再根據一樣的算法就能夠生成一份祕鑰,握手結束後的應用層數據都是使用這個祕鑰進行對稱加密。爲何要使用三個隨機數呢?這是由於 SSL/TLS 握手過程的數據都是明文傳輸的,而且多個隨機數種子來生成祕鑰不容易被暴力破解出來。客戶端將 PreMaster Key 傳給服務端的過程以下圖所示:
這一步是客戶端通知服務端後面再發送的消息都會使用前面協商出來的祕鑰加密了,是一條事件消息。
這一步對應的是 Client Finish 消息,客戶端將前面的握手消息生成摘要再用協商好的祕鑰加密,這是客戶端發出的第一條加密消息。服務端接收後會用祕鑰解密,能解出來講明前面協商出來的祕鑰是一致的。
這一步是服務端通知客戶端後面再發送的消息都會使用加密,也是一條事件消息。
這一步對應的是 Server Finish 消息,服務端也會將握手過程的消息生成摘要再用祕鑰加密,這是服務端發出的第一條加密消息。客戶端接收後會用祕鑰解密,能解出來講明協商的祕鑰是一致的。
應用層協議通訊即發送HTTP請求。
參考: