做者:drinkeygit
之前讀RFC時總結的一篇文章,主要介紹了SSL/TLS協議的相關知識,包括協議自己以及簡單的密碼學概念,以及用實例解析了HTTP over SSL的協商過程,在最後簡要列出了SSL的安全問題。github
RFC-2246: The TLS Protocol Version 1.0算法
詳細講述了TLS1.0的協議,TLS協議提供了一種Internet安全通訊方式,該協議容許客戶端和服務端通訊,並保證消息不被監聽,篡改和僞造。瀏覽器
描述瞭如何使用TLS協議來保證HTTP通訊的安全性服務器
RFC-3749: Transport Layer Security Protocol Compression Methodssession
描述了TLS壓縮的幾種方式併發
RFC-5216: The EAP-TLS Authentication Protocoldom
EAP-TLS認證協議jsp
RFC-5246: The Transport Layer Security (TLS) Protocol Version 1.2
TLS1.2協議文檔,在RFC2246基礎上有所發展
最初SSL協議是由netscape開發,並集成到瀏覽器中,用於保護HTTP傳輸安全性,做爲在傳輸層和應用層之間的一層,對更多的須要保護數據安全性的協議進行封裝。IETF以SSL協議爲基礎,提出了一種新的協議:TLS,創建在SSL V3.0的基礎上,是SSL 3.0的後續版本,已經開始在實際應用中使用。
雖然TLS和SSL不能互操做,僅僅是由於他們使用的加密算法和MAC算法不一樣,協議自己差異很是細微。RFC-2246是IETF提出的第一個版本,被稱做TLS v1.0,目前最新的版本是TLS v1.2,在RFC-5246中描述了其細節問題。
如下根據RFC5246,介紹SSL
協議由兩層構成:TLS Record Protocol
和TLS Handshake Protocol
。
TLS Record Protocol
處於較低的一層,基於一些可信任的協議,如TCP,爲高層協議提供數據封裝、壓縮、加密等基本功能的支持。它保證了通訊的兩個基本安全屬性:
1.保密鏈接。數據傳輸使用對稱加密算法,如AES,RC4等,該對稱加密算法的密鑰對於每一個鏈接是惟一的,基於密鑰協商協議生成,好比TLS handshake protocol
,Record Protocol
也能夠不使用加密。
2.可信鏈接。消息的傳輸包括了基於密鑰的消息認證碼(keyed MAC),使用安全Hash函數計算MAC,用於完整性檢查。Record Protocol
也能夠不使用MAC,可是這種模式只用於安全參數協商時。
Record Protocol
用於封裝多種高層的協議,其中一個種就是TLS handshake protocol
,這種協議容許客戶與服務器相互認證,在應用程序通訊前,協商加密算法和加密密鑰。TLS handshake protocol
保證了鏈接的三個基本安全屬性:
TLS協議提供的服務主要有:
TLS協議在協議棧中以下圖所示:
TLS協議對數據的封裝以下圖所示:
爲了便於更好的認識和理解SSL協議,這裏着重介紹SSL協議的握手協議,mail.qq.com支持SSL協議,如下結合實例,介紹SSL握手協議。數據包使用Wireshark抓取。對於文中提到的密碼學術語,在文章第5節有簡單解釋,可對照閱讀。
SSL 協議既用到了非對稱公鑰加密技術又用到了對稱加密技術,對稱加密技術使用於Record層,用於對傳輸的數據進行加密,公鑰加密技術使用於Handshake協議,提供了身份認證的功能。
SSL 的握手協議很是有效的讓客戶和服務器之間完成相互之間的身份認證,本實例中只有客戶端驗證服務端,服務端並無對客戶端進行驗證,通常相互進行身份認證的狀況在登陸銀行系統時會用到。
下面根據抓取到的數據包,分析瀏覽器訪問mail.qq.com時使用SSL協議的過程:
Cipher Specs字段是一個枚舉類型,說明了客戶端所支持算法,每一個Cipher Spec指定了一個加密組合,從下圖能夠看出,SSL與TLS的很顯著的區別就是,TLS支持了更多更先進更安全的加密組合,以下圖所示:
Random
是服務端產生的隨機數,根據一個隨機種子生成,這裏的隨機種子是gmt_unix_time,根據這個時間,使用僞隨機數函數(PRF)生成一個32字節的random_bytes。
Session ID
是一組任意字節數的序列,由server選出,用於識別鏈接是活動狀態仍是可恢復狀態。
Cipher Suite
指定了服務端選定的加密組合,這裏選出的加密組合是TLS_RSA_WITH_AES_256_CBC_SHA,RSA做爲認證算法,256位的AES分組加密算法做爲Record層加密payload使用的算法,SHA做爲消息認證碼算法,用於保證消息的完整性,防止消息被篡改。
Compress Method
代表了使用的壓縮算法,Record層接收高層協議的數據時,會將數據進行分片,前面已經提到過,對於每一個分片能夠選擇使用必定壓縮算法來提升加密和傳輸效率,這裏沒有使用壓縮算法,因此是null。
接着,服務端返回了證書,證書使用x.509格式,供客戶端驗證其身份,同時發送一個Server Hello Done消息。以下圖所示:
③客戶利用服務器傳過來的信息驗證服務器的合法性,服務器的合法性包括:證書是否過時,發行服務器證書的 CA 是否可靠,發行者證書的公鑰可否正確解開服務器證書的「發行者的數字簽名」,服務器證書上的域名是否和服務器的實際域名相匹配。若是合法性驗證沒有經過,通信將斷開;若是合法性驗證經過,將繼續進行第四步。
④用戶端隨機產生一個用於後面通信的密鑰,而後用服務器的公鑰(服務器的公鑰從步驟②中的服務器的證書中得到)對其加密,而後將加密後的「預主密鑰」傳給服務器(Client key exchange
)。該過程內容以下圖所示:
因爲預主密鑰的傳輸使用RSA進行了加密,因此沒法在抓取的數據包中顯示出來(在上圖中的Encrypted Handshake Message
),從而保證了握手過程的保密性。
⑤若是服務端要求客戶的身份認證(在握手過程當中爲可選,本例中沒有該步驟),用戶能夠創建一個隨機數而後對其進行數據簽名,將這個含有簽名的隨機數和客戶本身的證書以及加密過的預主密碼(Premaster secret
)一塊兒傳給服務端。
⑥若是服務端要求客戶的身份認證,服務端必須檢驗客戶證書和簽名隨機數的合法性,具體的合法性驗證過程包括:客戶的證書使用日期是否有效,爲客戶提供證書的CA 是否可靠,發行CA 的公鑰可否正確解開客戶證書的發行 CA 的數字簽名,檢查客戶的證書是否在證書廢止列表(CRL)中。檢驗若是沒有經過,通信馬上中斷;若是驗證經過,服務端將用本身的私鑰解開加密的預主密碼,而後執行一系列步驟來產生主密鑰(Master secret
)(客戶端也將經過一樣的方法產生相同的主通信密碼)。
若是服務端沒有進行步驟5,服務端端收到客戶端發送的使用服務端公鑰加密的預主密鑰,用私鑰解開加密的預主密鑰,執行一系列函數,生成會話的主密鑰,客戶端也進行相同的操做生成主密鑰。
⑦服務器和客戶端擁有了相同的主密鑰,雙方使用以前協商的對稱加密算法,並使用主密鑰做爲密鑰,用於 SSL 協議的安全數據通信的加解密通信。同時在 SSL 通信過程當中還要維護數據通訊的完整性,防止數據通信中的任何變化,經過消息認證碼來保證。
⑧客戶端向服務器端發出信息(Change cipher spec
),指明後面的數據通信將使用的步驟⑦中的主密碼爲對稱密鑰,同時通知服務器客戶端的握手過程結束。
⑨服務器向客戶端發出信息(Change Cipher Spec
),指明後面的數據通信將使用的步驟⑦中的主密碼爲對稱密鑰,同時通知客戶端服務器端的握手過程結束。
⑩SSL 的握手部分結束,SSL 安全通道的數據通信開始,客戶和服務器開始使用相同的對稱密鑰進行數據通信,同時進行通信完整性的檢驗。該過程的數據包以下圖所示:
今後過程開始,TLS Record層使用Application Data Protocol通訊,其Content-type字段變爲HTTP,這個字段記錄了上層協議的協議類型,以便數據提交到對方的TLS Record層後,對數據進行組裝,並交付給上層協議處理。
以上詳細闡述了基於TLS的HTTP協議(HTTPS)客戶端與服務端創建鏈接和握手的過程,如下對一些用到的密碼知識做爲補充,進行簡單的介紹:
PRF
:僞隨機數生成函數,用於生成任意大小的隨機序列。通常使用時間做爲初始化的隨機種子,經過PRF生成隨機序列,若是序列的長度不符合要求,則使用Hash函數對序列進行散列運算,通過幾輪迭代知道序列長度知足要求爲止。一個好的PRF能夠保證序列的隨機性最大化,防止猜想。
對稱加密算法
:如AES,DES,RC4。加密和解密的兩個過程使用相同的密鑰,經過加密和解密函數對數據進行操做,從而達到加密數據和解密數據的目的。
公鑰加密算法
:如DSA,RSA。通訊雙方共享各自的公鑰,傳輸時使用對方的公鑰對數據進行加密,接收方收到後,用本身的私鑰對數據進行解密。公鑰加密算法也被稱爲非對稱加密算法,由於加密和解密使用不一樣的密鑰。公鑰算法的數學依據是大素數的分解問題,理論上很難分解一個足夠大素數。常作認證和簽字用。
分組密碼
:不少對稱加密算法都是分組加密,先將須要加密的數據進行分組和填充,再將每一個分組使用加密函數進行加密,通過一些置換和迭代,獲得固定長度的輸出。
Hash函數
:如SHA,MD5。散列函數,具備單向性。散列函數對消息進行摘要,並通過迭代,獲得固定長度的輸出。消息的一個字節的變化對Hash函數的輸出都會有很大的影響。
MAC
:消息認證碼,由Hash函數對消息進行摘要獲得,因爲Hash函數的特性,能夠提供對消息完整性的驗證,通常隨消息一塊兒發出。
TLS協議大量的使用了以上密碼算法,從而保證了數據的完整性和保密性,密碼學是TLS協議安全的基礎,任何一種使用到的密碼算法被破解,將直接影響TLS協議的安全性。
TLS協議並非牢不可破的,使用了TLS的HTTP協議不必定安全。因爲TLS協議中有不少可選項,甚至能夠選擇Record層是否使用加密,若是沒有很好的配置,那麼TLS也不能保證傳輸的安全性。
2009 blackhat con中Marsh Ray提到了Renegotiating TLS attack,因爲TLS renegotiating的邏輯漏洞,形成在理想環境下,能夠實施中間人攻擊,這個攻擊是很是巧妙的,主要是利用了TLS/SSL 3.0重置加密算法機制和HTTP協議請求頭的key、value結構,實現了屢次數據的組合以完成本身想要的請求。
主要步驟以下:
1). 攻擊者鏈接目標站點完成SSL握手稱爲session 1,併發送GET /adduser.jsp?u=test&passwd=123 HTTP/1.1\r\nFVCK:
之類的數據包。
2). 攻擊者劫持被攻擊者訪問目標站點的數據,在session 1中轉發被攻擊者與目標服務器之間的SSL握手,被攻擊者和目標服務器完成握手稱爲session 2。
3). 目標站點和被攻擊者經過攻擊者的轉發完成握手,在session 2中被攻擊者發送本身的請求數據到目標服務器,相似於GET / HTTP/1.1\r\nHost: www.xxx.com\r\nAccept: */*\r\nCookie: admin=1\r\n\r\n
之類的數據。
4). 目標站點在一個SSL Session 1中接收到一個新的SSL Client Hello時,會認爲客戶端是在要求從新生成密鑰,由於在目標服務器看來session 2也是攻擊者發過來的,並且是相同的TCP session中。最終致使目標服務器認爲session 2是session 1密鑰重置以後的延續,會將兩次的數據組合到一塊兒。
5). 最終數據以下:GET /adduser.jsp?u=test&passwd=123 HTTP/1.1\r\nFVCK: GET / HTTP/1.1\r\nHost: www.xxx.com\r\nAccept: */*\r\nCookie: admin=1\r\n\r\n
。FVCK字段服務器不認識,真實請求GET / HTTP/1.1
當成了FVCK
字段的值,一塊兒被忽略掉,攻擊者成功的執行了添加WEB系統用戶的操做
詳細介紹參照Marsh Ray的原做:
http://extendedsubset.com/Renegotiating_TLS.pdf
文檔的最後展現了中間人攻擊的結果,成功得到了TLS協議上層協議的內容。
2014年Google公佈了SSLv3的漏洞,CVE-2014-3566,代號POODLE(Padding Oracle On Downgraded Legacy Encryption),目前只有經過服務端禁用SSLv3.0協議來防止此攻擊的發生。
知名的開源安全軟件OpenSSL一樣在2014年一樣也爆出了Heart bleed漏洞,形成攻擊者能夠直接讀取內存中的數據。