帶你看不同的https

前言

https並非一個協議,一般來講,若是咱們說使用了https,意思是說,咱們在http上使用了tls協議。 因而,咱們能夠更進一步的理解到:c++

  1. tls實際上不是特意爲http服務的一個協議。
  2. tls是應用層中比較下層的協議
  3. tls能夠應用於其餘應用層協議,好比郵件

爲何我比較強調這種層次概念,由於知識的邊界和概念須要劃分清晰,在遇到問題,才能知道突破口是在哪。我看大部分關於https文章會一上來就講一些握手過程,或者密碼學原理相關的內容,或者有些文章甚至沒有關於協議本書的說明,而是僅僅講抽象握手過程。我想,這樣的理解並無很結構化的去講好這樣一個東西,因此這也是我寫這篇文章的初衷。git

爲了容易理解,我會把比較結構性內容放在前面,把細節內容放在後面。github

宏觀看tls

上面一直在講tls,對於事先沒有了解過https的人來講,可能有點迷糊——tls是什麼? 瞭解過tls的人,應該也知道ssl協議。web

  • TLS:全稱是Transport Layer Security協議,意思就是傳輸層安全協議
  • SSL:全稱是Secure Sockets Layer協議,意思是安全套接層協議

從字面意思上來看,這兩個東西差很少,實際上,這兩個東西也能夠認爲是同樣的概念。tls就是ssl升級以後的版本,在早期時候(1994),爲了解決http自己的安全問題,網景公司建立了ssl協議應用於http協議,後來將ssl統一,應用於更普遍的應用層協議,進一步標準化ssl協議,也就是tls協議。算法

能夠把tls當成一層協議看待,那麼其於http的關係相似於:數組

爲什麼須要tls

上面提到,爲了解決http存在的安全問題,因此引入tls協議。咱們天然會有這樣的疑問,是什麼樣的安全問題,須要在協議上去作文章。瀏覽器

先總結這樣三個問題:安全

  1. 數據隱私問題
  2. 數據被篡改問題
  3. 身份認證問題

數據隱私:http協議是明文傳輸,也就是說若是中間人劫持請求,很容易理解到http協議傳輸內容的含義。有人可能會問:那咱們平時經過加密傳輸不就能夠解決了嗎,爲何須要在協議中大動干戈。這裏就須要點密碼學的常識,若是僅僅是簡單的加密數據,咱們有三種可選密碼方案,對稱加密,非對稱加密,單向散列或者mac算法,無論是對稱加密和非對稱加密,這意味着雙方都須要有解密用的鑰,對稱加密用的是同一個密鑰,非對稱須要各有一把相對的鑰匙。對於web這樣面向客戶端的傳輸,在客戶端植入密鑰明顯是不現實的行爲,因此可選方案中,密鑰怎麼安全傳輸變成了另外一個問題,也是tls協議握手協議解決的問題。至於不可逆的加密,好比登陸密碼自己,對於中間人攻擊,其實他並不須要知道你自己數據是什麼,這樣看似把數據隱私化,實際上並無達到安全效果。bash

數據被篡改:若是http協議無法防止被篡改。雖然有消息驗證碼,數字簽名能保證數據完整。可是單純一個密碼技術依然很難防止中間人攻擊服務器

身份認證問題:http是無狀態協議,因此驗證服務端身份是一件重要事情,證書認證也是https安全傳輸的一環

http確實存在這樣一些安全問題,雖然對使用者而言,確實有不少方法去預防安全問題,可是經過分析能夠發現,無法用簡單的方式,經過單一的一個種密碼學算法就能解決這些問題,通常來講,會組合各類密碼學算法,這是一個繁瑣的工做,因此tls也是將這些繁瑣的問題,統一成一個解決方案。

tls協議結構

tls是介於應用層協議和tcp協議紙之間的協議,tls協議能夠分紅兩層協議:

  1. 握手協議(TLS Handshaking Protocols)
  2. 記錄層協議(TLS Record Protocol)

結構如圖:

握手協議能夠分紅四個子協議: 結構如圖:

注:在tls 1.2版本以前,沒有heartbeat心跳協議,而是change cipher spec protocol密碼切換協議。

記錄層協議是接近tcp協議的底層協議,用來將握手協議定義消息封裝和下層協議通信。

握手子協議

握手協議能夠說是tls中最重要的子協議,由於它的職責就是協商出一種合適的 密碼套件 。上面也提到,解決一個安全問題不止一種加密算法,密碼套件正是一組各類不一樣功能算法的集合。通常須要兩個來回協商完成。

握手協議中以消息爲單位,消息格式如圖:

一個消息分紅是三個部分:

  1. 消息長度:佔用三個字節,用於定義消息最終長度大小
  2. 消息類型:佔用一個字節,tls握手協議中有不一樣的消息類型,每一個消息類型會帶不一樣的數據。
  3. 消息內容:大於一個字節,這是消息的主體內容

tls協議有十種不一樣的消息類型,分別是:

  1. hello_request: 0x00
  2. client_hello: 0x01
  3. server_hello: 0x02
  4. certificate: 0x0b
  5. server_key_exchange: 0x0c
  6. certificate_request: 0x0d
  7. servert_done: 0x0e
  8. certificate_verify:0x0f
  9. client_key_exchange:0x10
  10. finished: 0x14

握手過程

握手過程通常是兩個來回,主要用於交換不一樣的信息。tls1.2版本的握手過程,大致能夠如圖這樣抽象表示:

能夠看到,在通過兩個來回以後,客戶端和服務端就正式進入數據傳輸。在握手端來回中,不難發現,一個請求可能會帶好幾個握手協議不一樣的消息類型。這是由於,雖然握手協議會把不一樣消息交給記錄層協議,可是記錄層協議通常會把幾個類型封裝成一個數據塊發送。

圖中的*標記表示該消息會根據不一樣的密碼套件作調整,[]標記表示該協議並非握手協議定義的內容,可是也會在握手過程當中進行。顏色較淺部分屬於須要一個集合,綁定發送,這是雙向認證須要的環節。

接下來,就細看每個消息的含義把

Client Hello消息

上面流程圖中,客戶端首先會發起一個消息,這個消息結構以下:

struct {
        ProtocolVersion client_version;
        Random random;
        SessionID session_id;
        CipherSuite cipher_suites<2..2^16-2>;
        CompressionMethod compression_methods<1..2^8-1>;
        select (extensions_present) {
            case false:
                struct {};
            case true:
                Extension extensions<0..2^16-1>;
        };
} ClientHello; 
複製代碼

該數據定義了6個key:

  1. client_version:表示支持的最高版本號
  2. random:客戶端生出的隨機數,這裏你能夠先記下,finished消息中用prf算法生產主密鑰和密鑰塊會用到,生成預備主密鑰也會用到,避免重放攻擊。
  3. session_id:這個是會話重啓相關的,創建過https鏈接的客戶端能夠保存服務器給的id,若是這個值存在,則會走會話重啓的過程,而不是像項目那樣完整的流程
  4. cipher_suites: 客戶端支持的密碼套件
  5. compresson_methods: 壓縮算法,通常不會啓用壓縮算法
  6. extensions: 支持的擴展內容

因此說,消息並非很複雜。

server_hello

服務端的hello信息和客戶端同樣的結構

struct {
        ProtocolVersion server_version;
        Random random;
        SessionID session_id;
        CipherSuite cipher_suite;
        CompressionMethod compression_method;
        select (extensions_present) {
            case false:
                struct {};
            case true:
                Extension extensions<0..2^16-1>;
        };
} ServerHello;
複製代碼

具體就不重複描述了。

server certificate消息

這個消息是和上面的hello在一個請求的,能夠看到,握手協議發送完server_hello狀況之後就會發送certificate消息。可是因爲,一些密碼套件如DH_anon和DCDH_anon,不會發送該證書,因此該消息是可選的,可是大部分狀況,都會用到證書信息。

該消息主要承載證書信息,證書是作身份驗證的,該消息結構以下:

opaque ASN.1Cert<1..2^24-1>;

    struct {
        ASN.1Cert certificate_list<0..2^24-1>;
    } Certificate;
複製代碼

能夠看到只有一個certificate_list數組,該數組發送的是證書鏈,用於證書認證。 關於證書細節留到後面去講述。

server_key_exchange消息

若是certificate消息裏的證書信息不足以知足協商加密算法信息要求,會額外發送一個server_key_exchange信息做爲補充。有6種密碼套件是須要這個消息來發送的,以下:

DHE_DSS
DHE_RSA
ECDHE_ECDSA
ECDHE_RSA
------------------------
// 無證書
DH_anon
ECDH_anon
複製代碼

分割線以前的套件因爲使用的臨時的 DH/ECDH 密鑰協商算法,證書中是不包含這些動態的 DH 信息(DH 參數和 DH 公鑰),因此發送完證書信息以後會追加這個消息對DH信息作補充

分割線下面的兩種套件,屬於匿名協商,沒有證書信息,因此不會有certificate消息,可是因爲須要發送額外的靜態DH信息,因此會在這個消息裏追加發送。

對於不一樣公鑰密碼算法細節就不在這裏討論。

certificate_request消息

能夠看到,服務器端可能會發送一個certificate_request消息。該消息是可選的,同時是灰色,我用灰色表示,爲了說明該消息和其餘灰色信息的關係,同時,通常也不會出現。可是在雙向認證場景中,因爲須要客戶端也提供證書,因此服務端會發送這樣信息,要求客戶端也須要認證證書。

server_hello_done消息

上面流程圖,在發送完sertificate和exchange信息以後,服務端會緊接一個server_hello_done類型消息做爲結束。以後server會等待客戶端後續的工做。該消息結構十分簡單:

struct { } ServerHelloDone;
複製代碼

client_certificate消息

對於客戶端的certificate消息,該消息表示,若是在收到服務端發送的消息裏,包含certificate_request消息,則客戶端會根據自身條件發送證書信息。若是沒有客戶端沒有合適的證書信息,會發送一個空數組。

client_key_exchange消息

該消息不管如何都會發送,這個消息最大的做用是傳遞pre_master_key,也就是預備主密鑰,除了預備主密鑰,若是客戶端須要發送上面的certificate消息,還會對類型DH算法密鑰作補充信息。可是無論怎麼,生成pre_master_key是最重要對事,生成對pre_master_key是用於生成master_key的重要前提,生成master_key會在雙方拿到pre_master_key以後,在生成master_key以後,便會發送[ChangeCipherSpec]消息,轉換狀態。這意味着握手過程進入能夠加密階段。

其含義能夠參考上面服務端的server_key_exchange

[ChangeCipherSpec]協議

對於1.2版本的,在握手消息中,會涉及到協議狀態轉換,在1.3版本以後,該協議不在存在,可是爲了向下兼容,握手中可能還會有。該協議是用於改變協議狀態。

能夠理解爲,在上述的握手過程當中,收到該協議消息的端,狀態都爲:

pending read status 待讀狀態
    pending write status 待寫狀態
複製代碼

在接收到該信息以後,端狀態修改成:

current read status 可讀狀態
    current write status 可寫狀態
複製代碼

該消息表示,在握手過程當中,當進入可讀可寫狀態時,表示對端將進入加密階段,這也意味着,握手環節已經基本完成,具有加密傳輸的條件。

finished消息

在雙方發送完,會對握手中的重要信息進行驗證,驗證雙方會發送本身的校驗信息,消息結構以下:

struct {
        opaque verify_data[verify_data_length];
    } Finished;

    verify_data = 
        PRF(master_secret, finished_label, Hash(handshake_messages))
        [0..verify_data_length-1];
複製代碼

該消息的意義在於:握手過程當中全部的子消息都沒有加密和完整性保護,消息很容易篡改。爲了不握手期間存在消息被篡改的狀況,因此 Client 和 Server 都須要校驗一下對方的 Finished 子消息。

完成finish消息以後,最後雙方的通信會以master_key做爲對稱加密信息的主密鑰。

以上,是tls1.2定義的握手內容,固然,還有不少細節沒有研究,好比握手中涉及到的隨機數,session_id的做用。不過大致的過程已經講完了,後續慢慢補充一些細節。細節部分則須要一點密碼學常識。

細看tls

若是想更深刻理解,則須要瞭解部分密碼學相關內容,像上面提到的對稱加密,非對稱加密,隨機數,均屬於密碼學的內容。

密碼學常識

這裏簡單的介紹幾個密碼學概念,他們分別是:

  • 隨機數
  • 單向散列函數(hash算法)
  • 消息驗證碼(mac算法)
  • 數字簽名
  • 對稱加密算法
  • 公鑰加密算法

隨機數算法

隨機數做爲重要的密碼學單元,在密碼學中普遍運用到,密碼學單元是指:在其餘算法中,隨機數會產當一個因子的做用。好比生成對稱密碼和消息驗證碼。

隨機數有三個重要的特性:

  • 隨機性
  • 不可預測性
  • 不可從新性

三個特性關係能夠表示爲:

通常咱們把具備不可重現性的隨機數叫真隨機數,把具備不可預知的隨機數叫強僞隨機數,把具備隨機性的隨機數叫僞隨機數

只有至少具備強僞隨機數特性的隨機數算法才能用於密碼學。

單向散列函數

單向散列函數即one-way hash function。就是咱們常說的hash算法,對於用過md5算法的小夥伴應該不陌生。可是須要注意的是,單向散列函數的做用是保證消息的完整性。

單向散列函數具備這樣的特色:

  • 不一樣消息能達到固定長度的散列值
  • 抗碰撞,不一樣消息獲得的散列值不一樣
  • 單向性,沒法經過散列值得到原值
  • 高效

關於強抗碰撞和弱抗碰撞:

  • 強抗碰撞:對於任意散列值,找到相同消息的困難度
  • 弱抗碰撞:對於一個消息和其散列值,找到另一條不一樣消息,和該散列值相同的困難度

經過特色咱們能夠很容易的知道,單向散列能夠用來比較消息的完整性。由於其足夠小,足夠快,用來校驗不一樣內容是否完整頗有用。

缺陷: 固然,這也暴露了,單向散列函數的侷限性,就是沒法防止被篡改,也沒法驗證信息的來源。沒法防止篡改,是由於攻擊者很容易的能夠將不一樣消息生成散列而且假裝。好比中間人攻擊。

常見散列算法:

  • MD5
  • SHA(secure hash algorithms),SHA-1,SHA-2(256,512,224,384),SHA-3(256,5`1,224,384)

對稱加密算法

加密和解密都是用同一個密鑰的加密算法,叫對稱加密算法。對稱加密算法是在傳輸數據雙方持有一個相同的密鑰,這種算法須要解決最大問題就是密鑰的傳輸問題。 常見的對稱加密有AES,DES。

公鑰密碼算法

公鑰密碼算法就是非對稱加密算法,因爲前面提到的對稱加密算法的侷限性,因此很天然而然的聯想到,是否有一種傳輸數據雙方使用不一樣的密鑰的算法。公鑰密碼算法的解密模型也很簡單:

這裏須要提下,公鑰加密算法確實有更多可能性,可是我發現不少人有一些理解誤區:

  1. 就是非對稱就比對稱更優秀,或者說,更機密。我想這是不正確的,由於就機密性來講,取決於算法的密鑰長度,同時非對稱加密的性能不好,很難說一樣機密性,非對稱加密能作的比對稱加密好。
  2. 認爲非對稱加密能夠解決中間人攻擊,非對稱加密是解決不了中間人攻擊的,由於中間人只要劫持了公鑰,就能神不知鬼不覺的替換掉原來公鑰,用本身僞造的僞公鑰和僞密鑰瞞天過海。
  3. 非對稱算法在於它有使得傳輸過程當中有更多可選方案,好比數字簽名和密鑰協商中,都會用到非對稱加密的非對稱密鑰,這纔是公鑰算法的重要意義。

目前最經常使用的公鑰加密算法是RSA算法和ECC算法。

關於這兩個算法細節,這裏就不花時間描述了。ECC算法相對密鑰比RSA算法短,同時效率和機密性比RSA高。

公鑰加密算法的缺點就是執行效率太慢。

消息驗證碼(MAC)

消息驗證碼(message authentication code)是一種確認完整性,並認證的技術。簡稱MAC算法。

關於mac算法的理解須要結合以前的單向散列算法來看。咱們知道,單向散列算法能夠保證消息的完整性。

先看看二者的對比。

MAC算法相對單向散列算法而言,多了一個共享密鑰才能生成MAC值。這樣很容易聯想到,如何在網絡中傳輸密鑰是MAC算法的一個問題,這個問題和對稱加密算法中的問題同樣。

那MAC算法相對HASH算法解決了什麼問題呢,咱們知道,若是中間人攻擊了HASH算法生成的HASH值。因爲HASH算法和MAC算法不關注消息的機密性,因此中間人能夠對消息進行修改,同時用HASH算法從新生成HASH值從而達到篡改數據的效果。雖然MAC算法的密鑰若是被中間人劫持,同樣會遭受一樣的問題,可是咱們若是有一種方案,可以保證Mac密鑰不被劫持,就能防止中間人攻擊,這就是Mac算法存在的意義。

因此,在MAC算法密鑰安全的狀況下。mac能保證消息完整,同時可以認證,認證的含義是隻有持有密鑰的人能夠生成mac值。

那mac算法的有沒有其侷限性,除了說mac算法自己不是爲了機密性而生以外,mac算法依然沒法反正抵賴問題。如何理解抵賴?

咱們假設做爲第三者角度而言,用mac算法認證的消息雖然是完整的,可是若是有一天有一方對這個消息不認可,因爲發送方和接收方都有密鑰生成mac值,因此咱們沒法單從mac值中判斷說,這個消息是誰生成的。這就須要用到後面介紹的數字簽名技術。

數字簽名

數字簽名,是一種可以認證消息來源,保證數據準確性,防止篡改的技術。關於數字簽名,依然須要和單向散列算法和MAC算法作一個對比。

單向散列算法能夠保證消息完整準確性,含義在於只能保證在信息傳輸中不存在異常。可是沒法防止如中間人攻擊之類的,篡改數據,同時也沒法對消息進行認證。

Mac算法能夠保證消息準確同時,由於有一個共享密鑰,因此只要保證密鑰安全,就能反正數據被篡改,可是因爲數據傳輸雙方對密鑰是相同的,沒法經過第三方得知消息是誰發送的,即不能防止抵賴。

數字簽名在藉助公鑰密碼算法的密鑰不一樣的特色,實現了消息認證的機制。原理很簡單,就是生成消息的一方經過密鑰生成簽名,接受消息的一方,能夠經過公鑰解開消息而後認證消息的正確性。爲何數字簽名能夠反正抵賴,由於只有持有公鑰的人才能驗證消息,只有持有密鑰的人才能生成簽名。這樣雙方都沒法抵賴,同時也能保證消息的完整性,一樣能反正篡改。

關於數字簽名的簡單流程:

因爲簽名提到非對稱加密算法的性能不好,因此上面流程的比對,性能天然也很差,緣由是消息的長度可能很長,同時,對於rsa算法而言,須要加密的消息越長,其密鑰公鑰長度也要越長。聰明同窗很容易聯想到,使用單向散列算法可使消息生成簡單的hash值,同時,單向散列算法性能也很好。這樣就解決了這個問題,因此,通常的簽名算法流程優化以下:

補充:這裏作一點補充,在數字簽名裏,非對稱加密算法,經過密鑰加密生成簽名,經過公鑰解密驗證簽名。而在使用rsa作加密操做時,通常會用公鑰加密數據傳輸,而不會經過密鑰加密數據傳輸。緣由是由於,公鑰是公開對,任何人均可能得到,若是經過密鑰加密數據,任何人均可能拿到公鑰而後解密。

密鑰協商算法

回顧前面的技術,消息認證碼(MAC),對稱加密,以及用到這些技術的地方,都要強調密鑰重要性。可是在網絡傳輸過程當中,爲了雙方都能持有相同密鑰。咱們會思考如何傳輸密鑰。

這個就是密鑰如何配送的問題,關於解決密鑰配送問題,有如下幾種方式:

  1. 事先共享密鑰:好比直接在瀏覽器和服務器裏面事先內置須要的密鑰,這顯然是不太現實的作法
  2. 密鑰中心分配:創建一個專門管理密鑰的中心,由它來分配,可是這樣存儲量和維護成本就很大。
  3. 基於非對稱算法實現:由拿到公鑰的一端負責生成主密鑰,而且用公鑰加密發送主密鑰。這樣就能防止泄密,由於只有密鑰持有者能夠解密主密鑰。可是單純的這種方式會由中間人攻擊問題,要配合證書認證公鑰合法。
  4. 基於DH算法實現:DH算法會在兩端都保留各類私有信息,而且經過傳輸部分公共信息,兩邊經過公共信息生成主密鑰。而即便公共信息被拿到,第三方也沒法經過公共信息生成主密鑰,從而達到傳輸密鑰都效果。

這裏只講下DH的簡單過程,關於用非對稱算法傳輸密鑰很好理解,就再也不這裏描述:

在上面流程中,G,P,G^AmodP和G^BmodP是四個公開的數字。可是要經過這四個數字算出A,B數是很難的。

生成元G的意義: G的計算是比較複雜的,對於G^XmodP (1 < x < p 內的整數)的全部值都不一樣時,G就是P的元。而A,B隨機取0到P之間的全部整數。這樣,A,B有足夠多的選擇,同時計算有足夠多的可能性。

DH算法能防止中間人攻擊嗎?不能,中間人依然能夠經過中間篡改僞造A和B達到中間人攻擊的效果。

DH算法能夠和RSA這類非對稱算法作簽名,從而抵禦中間人攻擊。 DH算法和ECC算法進行結合升級新的密鑰寫書協商算法便是ECDH。

證書認證

證書認證的意義是給公鑰加上簽名,RSA算法在作密鑰協商,或者數據加密時。均可能被中間人給劫持僞造。可是若是有一種技術可以識別,公鑰有沒有被僞造,那就可以防止中間人攻擊。

這樣咱們很容易聯想到咱們以前談論到數字簽名技術,由於數字簽名不只能保證數據不被篡改,還能防止抵賴。可是,聰明的你應該很容易聯想到,數字簽名也是要用公鑰算法作簽名。怎麼保證簽名都機構都公鑰安全又是另外一個問題。

因而,咱們想象若是有這樣一個機構,他用本身都私鑰給客戶都公鑰進行簽名。而後這樣都機構公開本身都公鑰,由於中間人沒有機構都私鑰,這樣中間人沒法僞造簽名。就沒法僞造客戶都公鑰了。

這樣又有新都問題,咱們憑什麼想象這個機構。事實到這裏,咱們確實只能想象這個機構,別無他法。這個機構就是CA機構。

因此,證書其實就是給客戶的公鑰和信息加上一個數字簽名,有了這個數字簽名。就無法僞造公鑰。

可是,新的問題是,在作數字簽名認證時,咱們須要用到CA機構的公鑰進行認證,若是經過網絡的方式去獲取公鑰,這個公鑰有沒可能被攻擊者劫持,是有可能的。因此比較好的作法是把CA機構的信息內置到操做系統中。不經過網絡獲取。可是若是CA機構的數量過於龐大,怎麼辦。因此實際上,CA機構分爲 CA根機構CA中間機構。在操做系統中只要內置根證書就好了。經過根證書給下一級機構簽名,而中間機構經過網絡傳輸也沒有關係,只要更證書是安全的,就能經過簽名發現中間機構是否被僞造。這樣就解決了傳輸問題。

再看握手過程

經過前面關於密碼學的瞭解。這裏能夠更深刻的去思考握手過程。 此次咱們先明確握手的目的,看上圖中的過程,握手過程最終是爲了數據傳輸服務的。也就是後續數據傳輸中的application data過程。

記錄層協議

數據傳輸是在記錄層協議中的定義的,關於記錄層協議,主要是完成一下的功能:

  1. 裝載由上層協議分發下來的消息
  2. 有選擇的壓縮數據
  3. 對數據進行加密,解密和mac認證

因此,在握手結束後,通常會採用對稱加密算法加密數據,而後作mac認證。握手過程爲了給傳輸數據提供會話密鑰。而tls 1.2版本在PRF函數中使用加密基元是 SHA256 算法。

在握手過程當中,最終會生成三個密鑰分別是:

  1. 預備主密鑰(pre_master_key)
  2. 主密鑰(master_key)
  3. 會話密鑰(session_master_key)

在前面的握手過程當中,咱們看到第一個來回,協商了主要的密碼套件,而且客戶端和服務端交換了以一對隨機數,分別是client_random,和server_random。忘記的回去看hello消息的結構。

上面的主密鑰是經過PRF函數和隨機數計算得來:

PRF(pre_master_secret, "master secret",
    ClientHello.random + ServerHello.random)
    [0..47];
複製代碼

計算時間前面提到過,是在校驗完證書以後。

以rsa協商爲例,預備主密鑰,則由客戶端隨機生成,而後經過公鑰發送,也就是client_key_exchange的那個消息中生成。

這裏能夠根據密碼學原理提出幾個解答:

  1. 爲何是由客戶端生成預備主密鑰中,經過公鑰加密發送。 答:在前面提到的rsa密鑰協商中,經過公鑰一方去發送密鑰信息,第三方沒法解密出密鑰信息,由於第三方必須用非對稱中的私鑰去解密,可是私鑰是不公開的。相反,若是是經過私鑰加密,則因爲公鑰是公開的,第三方很容易解密獲得密鑰。

  2. 若是是dh算法相關的協商,如何獲取到預備主密鑰。 答:加入不是rsa做爲密鑰協商,那麼雙方會在exchange信息中交換公共信息,而後計算出預備主密鑰,預備主密鑰就不會進行網絡傳輸。本質上是沒有變化的。

  3. 在1問題中,經過rsa密鑰協商不是會遭遇中間人攻擊嗎? 答:密碼學章節已經講過,證書技術是如何防止中間人攻擊的,也就是通過證書籤名的公鑰是安全的,中間人沒法僞造。因此不會有中間人攻擊。

而會話密鑰是記錄層中經過主密鑰生成的數據。該數據會被拆成幾部分,分別用於加密解密,和mac認證。

會話重啓

tls 1.2有兩種會話重啓的方式,分別:

  1. 基於Session Id
  2. 基於Session Ticket

基於Session Id流程:

基於session的方式,在客戶端發送第一個hello的時候,會帶上消息中的session_id,該id是在完整握手中由服務器生成,而且保存在服務器內存中。 會話重啓中會保留以前的主密鑰,會話密鑰會從新生成。這樣能夠防止前向安全性。

這種重啓方式有session的通病,就是比較佔用服務器資源,由於session是服務器生成而且保存在服務器中。

相比session的重啓方式,基於ticket的方式就是在客戶端存儲會話,服務端不作存儲。不過每次重啓會更新ticket。流程以下:

參考資料:

  1. <<圖解密碼學>>
  2. <<深刻淺出https>>
  3. https
相關文章
相關標籤/搜索