1. 程式人生 > >SSL連接分為兩個階段:握手和數據傳輸階段

SSL連接分為兩個階段:握手和數據傳輸階段

tps 2.4 網絡 change 多少 number 系列 bit 客戶端

一、SSL概述
SSL連接分為兩個階段:握手和數據傳輸階段。握手階段對服務器進行認證並確立用於保護數據傳輸的加密密鑰,必須在傳輸任何應用數據之前完成握手。一旦握手完成,數據就被分成一系列經過保護的記錄進行傳輸。

1.1.握手
SSL握手有三個目的:

客戶端與服務器需要就一組用於保護數據的算法達成一致;
他們需要確立一組由那些算法所使用的加密密鑰;
握手可以選擇對客戶端進行認證。
整個工作過程如下圖:

(1)客戶端將它支持的算法列表+用於密鑰產生過程的隨機數發送給服務器;
(2)服務器從列表中的內容選擇一種加密算法,並將其連同一份包含服務器公用密鑰的證書發回給客戶端;(證書包含了用於認證目的的服務器標識,同時,服務器還提供了一個作為密鑰產生過程部分輸入的隨機數)

(3)客戶端對服務器的證書進行驗證,並取出服務器的公用密鑰(用於之後加密發給服務器的信息);然後產生一個稱為pre_master_secret的隨機密碼串,並使用服務器的公用密鑰對其進行加密。最後,客戶端將加密後的信息發送給服務器;
(4)客戶端與服務器根據pre_master_secret以及客戶端與服務器的隨機數獨立計算出加密和MAC密鑰;
(5)客戶端將所有握手信息的MAC值發送給服務器;
(6)服務器將所有握手信息的MAC值發送給客戶端。
通過上述過程,就已經達到了SSL握手三個目的中的前兩個目的了。其中,第一步和第二步實現了第一個目標(確立一種加密算法);第二步和第三步實現了第二個目標,在第2步中,服務端向客戶端提供服務器公用密鑰的證書,這樣就允許客戶端給服務器傳送密碼。經過第三步後,兩端都知道了pre_master_secret(客戶端知道是因為這是它產生的,服務端知道是因為它利用私密密鑰解密得到的)。第四步,兩端采用相同的密鑰導出函數(KDF)來產生master_secret,最後再次通過KDF使用master_secret來產生加密密鑰。最後兩步是防止握手本身遭到篡改。

對應著上一張圖和這一張圖,握手過程是通過一條或者多條消息實現的。

第 1 步對應一條單一的握手消息, ClientHello。
第 2 步對應一系列 SSL 握手消息,服務器發送的第一條件消息為 ServerHello,其中包含了它所選擇的算法,接著再在 Certificate 消息中發送其證書。最後,服務器發送ServerHelloDone 消息以表示這一握手階段的完成。需要 ServerHelloDone 的原因是一些更為復雜的握手變種還要在 Certificate 之後發送其他一些消息。 當客戶端接收到 ServerHelloDone消息時,它就知道不會再有其他類似的消息過來了,於是就可以繼續它這一方的握手。

第 3 步對應 ClientKeyExchange 消息。
第 5 與第 6 步對應 Finished 消息。 該消息是第一條使用剛剛磋商過的算法加以保護的消息。為了防止握手過程遭到篡改,該消息的內容是前一階段所有握手消息的 MAC 值。然而,由於 Finished 消息是以磋商好的算法加以保護的,所以也要與新磋商的 MAC 密鑰一起計算消息本身的 MAC 值。
二、SSL記錄協議
在SSL中,實際的數據傳輸是使用SSL記錄協議來實現的。SSL記錄協議時通過將數據流分割成一系列的片段並加以傳輸來工作的,其中對每個片段單獨進行保護和傳輸。在接收方對每條記錄單獨進行解密和驗證。

在傳輸片段之前,通過計算數據的MAC來提供完整性保護。MAC與片段一起傳輸,並由接收實現加以驗證。將MAC附加到片段的尾部,並對數據與MAC整合在一起的內容進行加密,以形成經過加密的負載。最後給負載裝上頭部信息。頭信息與經過加密的負載的聯結稱為記錄(Record),記錄就是實際傳輸的內容。

2.1.記錄頭信息
記錄頭信息的工作就是為接收實現提供對記錄進行解釋所需的信息。在實際應用中是指三種信息:內容類型、長度和SSL版本。

長度字段:可讓接收方知道它要從線路上讀取多少直接才能對消息進行處理;
版本號:確保每一方使用所磋商的版本的冗余性檢查;
內容類型:標識消息類型。
2.2.內容類型
SSL支持四種內容類型:application_data、alert、handshake和change_cipher_spec。

application_data:使用SSL軟件發送和接收的所有數據都是以application_data類型來發送的;
alert:主要用於報告各種類型的錯誤;
handshake:承載握手消息;
change_cipher_spec:標識記錄加密以及認證的改變,一旦握手商定了一組新的密鑰,就發送change_cipher_spec來指示此刻將啟用新的密鑰。
2.3.SSL規範語言
TLS和SSLv3都是使用同一種規範語言來描述他們各自的消息的。規範使用五種基本類型:opaque、uint8、uint16、uint24和uint32,分別對應無符號的8-、16-、24-和32-位整數,並在線路上以1、2、3或4字節序列加以表示。所有的數字都以“網絡字節順序”——高位在前來表示。

2.3.1.向量vector
向量是給定元素類型的元素序列,分為定長和變長向量。其中,定長向量用[]表示,變長向量用<>表示。長度以字節而不是元素個數為單位,所以uint16 foo[4]是表示是指兩個16位整數,而不是4個!(長度為4字節,uint16位16位整數,即兩字節整數,因此4個字節包含兩個16位整數)。這樣就允許解碼器具有分層的結構,它可以將結構當做不透明的字符串(因為它知道它們的長度)來看待,並將其傳送給另一層加以解析。

此外,可以通過長度的上限與下限、或只指定上限來表示變長向量。

// A string of between 1 and 20 bytes
opaque stuff<1..20>

// Up to 4 32 bit integers
uint32 numbers<16>
2.3.2.枚舉類型
枚舉類型就是假定只有一系列特定值的字段,且每個值都有名字。

enum{red(1),blue(2),green(3)}colors;
指定一個名為colors 的類型,他們可以接收值red、blue和green,在線路上用整數1、2和3來表示。當在線路上對枚舉變量進行編碼時,用一個大到足以容納其最大值的整數類型來表示,因此用一個字節的uint8來表示colors。也可以通過顯式包含一個未命名的值來為一個枚舉變量顯式指定最大尺寸:

enum{warning(1),fatal(2),(255)}AlertLevel;
2.3.3.結構
使用struct來構造結構化類型(與C語言類似):

struct{
type1 field1,
type2 field2,
type3 field3,
……
}name;
2.3.4.變體類型
可以將結構定義成依賴外部信息而變化的變體(Variant)類型,使用一種表面上看起來類似於C語言中的switch語句的結構來進行定義(類似於C語言中的union):

select(type){
case value1:Type1
case value2:Type2
……
}name;
2.4.握手消息結構
頭信息為4字節長,包括一個字節的類型字段和3個字節的長度字段組成,長度字段表示剩余握手消息的長度(不包括類型與長度字段),余下的消息內容完全有賴於msg_type字段。

struct{
HandshakeType msg_type;
uint24 length;
select(HandshakeType){
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
}body;
}Handshake;

enum{
hello_request(0),client_hello(1),server_hello(2),
certificate(11),server_key_exchange(12),certificate_request(13),
server_hello_done(14),certificate_verify(15),client_key_exchange(16),
finished(20),(255)
}HandshakeType;

---------------------
作者:馮Jungle
來源:CSDN
原文:https://blog.csdn.net/sinat_21107433/article/details/88366880
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

SSL連接分為兩個階段:握手和數據傳輸階段