HTTP是明文傳輸協議,數據容易被竊聽和篡改,攻擊者很容易偽裝成客戶端和服務器。HTTPS可以解決這兩個國家的安全問題。HTTS仍然是HTTP協議,但是在HTTP和TCP之間增加了TSL/SSL協議來加密數據。其他很多應用層協議也在傳輸層增加了TSL/SSL協議來保證安全性,比如FTPS和IMAPS。
加密和解密使用相同的密鑰。加密和解密都需要持有相同的密鑰。常見的對稱加密算法:AES,DES,3DES。
加密和解密使用不同的密鑰,加密時使用的密鑰稱為公鑰,解密時使用的密鑰稱為私鑰。用公鑰加密的密文只能用私鑰解密。公鑰可以釋放使用,但私鑰壹定不能泄露。常見的非對稱加密算法:RSA,背包算法,ECC。
數字簽名用於檢查數據是否被篡改,即數據是否與原始數據壹致。
數字簽名包括兩個操作:簽名和驗證。數字簽名是不可否認的,在簽名被驗證正確後也不能否認。
數字簽名通常包含壹個已知的私鑰和壹個公鑰。與傳統加密不同,簽名時使用私鑰,公鑰用於驗證簽名。
1994網景提出了SSL協議,並制定了SSL協議的原始規範,即SSL1.0。但是SSL1.0因為使用弱加密算法而受到密碼學的質疑,所以SSL1.0壹直沒有公開發布。
繼SSL1.0之後,Netscape對SLL協議規範進行了重大改進,並於1995發布了SSL2.0協議。雖然SSL 2.0版被認為是壹個非常強大和健壯的協議,但仍然存在壹些易受攻擊的漏洞,因此它沒有得到廣泛應用。
因為SSL2.0的安全問題,網景和哈佛的Paul Kocher重新設計了SSL協議,並在1996發布,即SSL2.0版,與2.0版有很大不同。SSL 3.0協議得到了互聯網的廣泛認可和支持。
隨著互聯網的快速發展,網絡安全越來越重要,業界迫切需要壹個標準的安全協議,於是IETE接手了SSL協議,並將其更名為TSL(傳輸層安全協議),並在1999發布了TSL1.0版本。
但是TSL1.0和SSL3.0差別不大(TLS 1.0裏面的協議版本號其實是3.1)。
雖然TSL是SSL的升級版,但是在壹些術語上還是有壹些混亂,所以人們通常稱之為SSL/TLS協議。
TSL1.1發布於2006年,主要是為了修復壹些漏洞。
TSL1.2發布於2008年。1.2版本主要是去掉了壹些舊的加密套件,引入了AEAD加密模式。1.2版本是目前應用最廣泛的版本。
TSL1.3發布於2018。1.3版本是2014年提出的,經過4年的反復修改,直到第28稿才正式納入標準。
與1.2版本相比,1.3版本有了很大的變化,不僅增強了安全性還大大提高了訪問速度。主要變化如下:
在公網通信時,為了保證通信信道的安全,目前只能對通信數據進行加密,以防止竊聽、冒充和篡改。
為防止竊聽:
數據加密後,傳輸加密的密文。即使密文被竊聽,沒有解密密鑰也無法獲得真實內容。
防偽和篡改:
當通信的數據被加密傳輸時,沒有加密密鑰是不可能構造合法的數據包的,所以不可能冒充或篡改數據。
對通信數據進行加密傳輸可以解決很多安全問題,但實現通信加密的關鍵點是如何協商用於加密的密鑰,以保證密鑰不會被泄露和篡改。關鍵協議是HTTPS最大的困難。
通信中使用對稱加密,當客戶端請求時,對稱加密密鑰直接返回給客戶端。
但是在安全通道建立之前,任何傳輸都還是明文,使用明文加密密鑰沒有安全性,對稱加密使用的是同壹個密鑰,所以第三方在竊聽到密鑰後可以竊聽和篡改數據,也可以偽裝成客戶端和服務器。所以直接分發對稱加密密鑰顯然是不可行的。
為了解釋方便,我們只看客戶端向服務器單向發送數據的情況,服務器也以類似的方式向客戶端發送數據。
通信中使用非對稱加密,當客戶端請求公鑰時,公鑰被放回客戶端。
但是公鑰返回的時候還是明文傳輸,所以公鑰還是會很容易被泄露。公鑰泄露後,雖然第三方沒有密鑰無法竊聽數據或直接冒充服務器,但由於公鑰泄露,第三方仍然可以冒充客戶端或進行‘中間人’攻擊。
所以單純使用非對稱加密是不可行的。
中間人攻擊:
只要通信中使用的密鑰不被泄露,就不需要在通信中使用非對稱加密。畢竟對稱加密效率更高。因此,在正式開始通信之前,可以使用非對稱加密來協商通信中使用的對稱加密密鑰,步驟如下:
雖然對稱加密和非對稱加密的結合可以給我們兩者的優勢,但仍然無法避免‘中間人’攻擊。
DH密鑰協商算法不直接交換密鑰,而是使用參數來產生密鑰。DH算法無法基於目前的‘無力’將大數分解為素數,以保證即使參數泄露,第三方也無法通過參數推導出密鑰。
DH算法密鑰協商步驟:
通過以上步驟,客戶端和服務器協商密鑰S,整個過程中不傳輸S。為了防止被破解,A和B通常很大,P是至少300位的質數,G通常很小,壹般是3或5。
但是DH算法的缺點也很明顯。DH防不住冒名頂替,中途還是會被人攻擊。
數字證書又稱公鑰證書或身份證書,用於頒發公鑰,證明公鑰所有者的身份。
該證書由第三方機構頒發,用於驗證服務提供商的合法性。使用時,服務提供商將證書交給客戶端,客戶端通過特定的機制驗證證書的合法性,從而信任提供證書的服務器和證書中的公鑰。
數字證書以文件的形式存在,文件中包含公鑰信息、所有者身份信息(主體)和數字證書認證機構(頒發者)的數字簽名。證書的數字簽名用於確保證書未被篡改。
壹般我們向CA申請證書時,不需要提供公鑰和私鑰。CA會給我們分配壹個密鑰對,把公鑰寫入證書,然後給我們證書和私鑰。
證書有統壹的標準,其合法性(證書是否過期、數字簽名是否有效、簽發機構是否可信)通過壹定的程序按照標準進行驗證。比如瀏覽器會保證HTTPS證書是否合法,Linux下的openSSL庫提供了證書驗證功能。
檢查證書後,如果證書可信,可以使用證書中的公鑰加密數據,並與證書的所有者進行通信。
HTTPS的證書在擴展字段中包含了與域名相關的信息,因此CA在申請證書時會嚴格檢查申請證書的組織或個人是否真正擁有該域名。
數字證書頒發機構(CA)。證書的標準是開放的。誰都可以做證書,但是自己做的證書不可信。只有由權威CA組織頒發的證書可以被信任。
權威CA證書審核部署流程嚴謹復雜,所以權威根證書的有效期壹般在幾十年之內。
只有權威CA的根證書才會得到各大操作系統的支持,並預制在操作系統中。
證書壹般遵循X.509規範,主要包括以下內容:
CA生成的證書不僅包含上述內容和壹些擴展字段,還包含CA用自己的私鑰加密的密文。在驗證證書時,使用CA的根證書來驗證秘密,從而判斷證書是否合法。
頒發機構使用根證書頒發輔助CA證書,輔助CA證書可以向其他服務頒發證書。但是,並不是所有證書都可以繼續頒發新證書。證書使用基本約束擴展來限制證書的頒發,我們壹般申請的證書基本約束擴展是假的。查看根證書的基本約束,可以看到證書頒發機構是' Yes '。
根證書不直接為服務頒發證書,只要它們基於以下兩點:
上層證書對下層證書進行簽名,簽名值包含在證書中。您可以使用上層證書中的公鑰來驗證下層證書的簽名值。根證書的簽名是自簽名的,驗證簽名的公鑰包含在根證書中。
完整的證書公司的關系應該是服務器放回去的,但是有壹部分沒有放回去。對於沒有放回的證書,證書中的擴展字段CA key identifier記錄了該證書的最後壹張證書,通過該字段獲取上層的中間證書,然後從中間證書的該字段繼續查找,直到根證書。
服務器最好返回證書鏈接,避免瀏覽器自己找,提示握手速度。服務器返回的證書鏈不包含根證書,根證書預先存儲在操作系統中。
Openssl庫將在linux中集成根證書。通過‘openssl version-a’查看OpenSSL根證書的存儲路徑。
在檢查證書時,首先按照證書鏈逐級檢查證書的簽名,簽名檢查的關鍵是根證書。根證書是預加載到操作系統中的,CA很難將自己的證書預加載到各種系統中,所以在系統中預加載根證書是可信的。
回過頭來看,對於HTTPS的證書,CA在申請時會嚴格核實,確保域名屬於申請該證書的機構。這樣,攻擊者可能會偽造證書來更改域名,但偽造證書的根證書不會存在於系統中,因此偽造的證書不會被信任。這樣,通過證書鏈的驗證,可以有效地防止服務器被“冒充”。
以上證書數字簽名驗證後,只驗證證書確實是合法證書,然後驗證證書的有效性。有效性驗證主要包括以下字段:
有效的證書也可能由於各種原因被撤銷,例如證書私鑰的泄漏、證書的錯誤發行等。為了驗證證書是否有效,引入了證書撤銷機制。
OSCP是由證書提供者提供的證書驗證接口,用戶可以通過調用OSCP接口來驗證證書是否被撤銷。
但是,由於策略或服務失敗,OCSP服務可能無法訪問。這時候壹般瀏覽器都會選擇信任證書。畢竟證書被吊銷的情況很少。還有壹些ca將OCSP失敗後的策略寫入證書的擴展字段,用戶可以根據擴展字段進行處理。
OSCP模式有其明顯的缺陷。為了驗證證書,當您請求OSCP時,您還需要告訴CA您訪問了什麽服務。如果我們利用我們的訪問數據作惡,CA該怎麽辦?而OCSP的慢界面會拖慢我們服務相應的數獨。為了解決這兩個問題,各大CA廠商聯合推出了CRL方案。
CRL方案是定期將吊銷的證書列表拉到本機,壹般是幾天壹次。驗證證書時,請在本地列表中查找它。
CA將在證書的擴展字段中寫入CRL的更新地址:
CRL也有自己明顯的決心。第壹,CRL是定時拉的,不能保證實時有效,然後CRL的列表很可能達到數米。
CRLSet是chrome自建的解決方案。Google認為CRL更新太慢,每個CA都有自己的CRL,CRL內容太多。所以我設置了壹個CRLSet,將主要CA的已撤銷的高風險證書添加到CRLSet中。chrome可以檢查自己CRLSet中的證書。
CRLSet只有每個CA吊銷的部分證書,包含所有吊銷證書的2%左右。
CRLSet的更新比較快,最遲每隔幾個小時就會從各個CA更新壹次。當證書急需撤銷時,可以使用CRLSet使撤銷快速生效。
CRLSet提供/agl/CRLSet-tools工具來提取並驗證證書是否在CRLSet中。
可以在chrome://components/中更新chrome的CRLSet
客戶端向服務器發送hello請求,其中包含客戶端的SSL/TSL版本、支持的加密套件和隨機數Random1。
服務器收到客戶端的hello後,根據客戶端支持的加密套件和自身支持的加密套件選擇後面要使用的加密和哈希套件,並返回給客戶端,同時返回服務器產生的隨機數Random2。
服務器將自己的證書返回給客戶端,客戶端收到證書後通過檢查證書信任服務器,並從證書中獲取證書中的公鑰。
返回證書後,服務器將立即向客戶端發送請求。然而,該請求不是必需的,並且僅當所選加密套件需要附加參數時,才會發送請求交互參數。
如果密鑰協商商算法是DH算法,那麽DH的參數將在這個請求中返回給客戶端。DH算法如下:DHE_DSS,DHE_RSA,ECDHE_ECDSAECDHE_RSA。
dh算法將返回參數p、g、dh的公鑰及其簽名,其中公鑰是g^b mod p,b是服務器的隨機數。
這裏g是0X03,p是0X0017。
服務器發送上述信息後,會立即發送服務器Hello Done通知客戶端服務器的相關信息已經發送,只等客戶端開始密鑰協商。
收到消息後,客戶端開始驗證證書並協商密鑰。
在從服務器接收到服務器Hello Done信息後,客戶會計計算出初步主密鑰並將其返回給服務器。
如果使用RSA/ECDSA算法,則發送準備好的主密鑰。
如果使用DH算法,發送的是前面參數統計的公鑰,即B (G b mod P)服務器收到B後通過B a mod P得到第三個隨機數,客戶端通過s = A b mod得到了s。
此時,服務器和客戶端已經得到了三個隨機數,通過之前協商好的加密算法,利用這三個隨機數得到壹個對稱的加密密鑰,在以後的通信中使用。
該請求用於通知對方用於通信的密鑰已經計數,所有後續通信將使用該密鑰進行。服務器和客戶端都會發送請求,通常是服務器先發送。
完成上述步驟後,發送雙方都會向對方發送完成請求,完成的數據用協商好的密鑰加密,驗證之前協商好的密鑰和協議版本是否有效。
參考資料: