一、https 建立連線
當你在瀏覽器位址列裡鍵入「https」開頭的 uri,再按下回車,會發生什麼呢?
瀏覽器首先要從 uri 裡提取出協議名和網域名稱。因為協議名是「https」,所以瀏覽器就知道了埠號是預設的 443,它再用 dns 解析網域名稱,得到目標的 ip 位址,然後就可以使用三次握手與**建立 tcp 連線了。
在 http 協議裡,建立連線後,瀏覽器會立即傳送請求報文。但現在是 https 協議,它需要再用另外乙個「握手」過程,在 tcp 上建立安全連線,之後才是收發 http 報文。
二、tls 協議的組成
tls 包含幾個子協議,你也可以理解為它是由幾個不同職責的模組組成,比較常用的有記錄協議、警報協議、握手協議、變更密碼規範協議等。
記錄協議(record protocol)規定了 tls 收發資料的基本單位:記錄(record)。它有點像是 tcp 裡的 segment,所有的其他子協議都需要通過記錄協議發出。但多個記錄資料可以在乙個 tcp 包裡一次性發出,也並不需要像 tcp 那樣返回 ack。
警報協議(alert protocol)的職責是向對方發出警報資訊,有點像是 http 協議裡的狀態碼。比如,protocol_version 就是不支援舊版本,bad_certificate 就是證書有問題,收到警報後另一方可以選擇繼續,也可以立即終止連線。
握手協議(handshake protocol)是 tls 裡最複雜的子協議,要比 tcp 的 syn/ack 複雜的多,瀏覽器和伺服器會在握手過程中協商 tls 版本號、隨機數、密碼套件等資訊,然後交換證書和金鑰引數,最終雙方協商得到會話金鑰,用於後續的混合加密系統。
最後乙個是變更密碼規範協議(change cipher spec protocol),它非常簡單,就是乙個「通知」,告訴對方,後續的資料都將使用加密保護。那麼反過來,在它之前,資料都是明文的。
三、抓包的準備工作
在 tcp 建立連線之後,瀏覽器會首先發乙個「client hello」訊息,也就是跟伺服器「打招呼」。裡面有客戶端的版本號、支援的密碼套件,還有乙個隨機數(client random),用於後續生成會話金鑰。
handshake protocol: client helloversion: tls
1.2 (0x0303
) random: 1cbf803321fd2623408dfe…
cipher suites (
17suites)
cipher suite: tls_ecdhe_rsa_with_aes_128_gcm_sha256 (
0xc02f
) cipher suite: tls_ecdhe_rsa_with_aes_256_gcm_sha384 (
0xc030)
這個的意思就是:「我這邊有這些這些資訊,你看看哪些是能用的,關鍵的隨機數可得留著。」
作為「禮尚往來」,伺服器收到「client hello」後,會返回乙個「server hello」訊息。把版本號對一下,也給出乙個隨機數(server random),然後從客戶端的列表裡選乙個作為本次通訊使用的密碼套件,在這裡它選擇了「tls_ecdhe_rsa_with_aes_256_gcm_sha384」。
handshake protocol: server helloversion: tls
1.2 (0x0303
) random: 0e6320f21bae50842e96…
cipher suite: tls_ecdhe_rsa_with_aes_256_gcm_sha384 (
0xc030)
這個的意思就是:「版本號對上了,可以加密,你的密碼套件挺多,我選乙個最合適的吧,用橢圓曲線加 rsa、aes、sha384。我也給你乙個隨機數,你也得留著。」
然後,伺服器為了證明自己的身份,就把證書也發給了客戶端(server certificate)。
接下來是乙個關鍵的操作,因為伺服器選擇了 ecdhe 演算法,所以它會在證書後傳送「server key exchange」訊息,裡面是橢圓曲線的公鑰(server params),用來實現金鑰交換演算法,再加上自己的私鑰簽名認證。
handshake protocol: server key exchangeec diffie-hellman server params
curve type: named_curve (
0x03
) named curve: x25519 (
0x001d
) pubkey: 3b39deaf00217894e...
signature algorithm: rsa_pkcs1_sha512 (
0x0601
) signature: 37141adac38ea4...
這相當於說:「剛才我選的密碼套件有點複雜,所以再給你個演算法的引數,和剛才的隨機數一樣有用,別丟了。為了防止別人冒充,我又蓋了個章。」
之後是「server hello done」訊息,伺服器說:「我的資訊就是這些,打招呼完畢。」
這樣第乙個訊息往返就結束了(兩個 tcp 包),結果是客戶端和伺服器通過明文共享了三個資訊:client random、server random 和 server params。
客戶端這時也拿到了伺服器的證書,那這個證書是不是真實有效的呢?
這就要用到第 25 講裡的知識了,開始走證書鏈逐級驗證,確認證書的真實性,再用證書公鑰驗證簽名,就確認了伺服器的身份:「剛才跟我打招呼的不是**,可以接著往下走。」
然後,客戶端按照密碼套件的要求,也生成乙個橢圓曲線的公鑰(client params),用「client key exchange」訊息發給伺服器。
handshake protocol: client key exchangeec diffie-hellman client params
pubkey: 8c674d0e08dc27b5eaa…
現在客戶端和伺服器手裡都拿到了金鑰交換演算法的兩個引數(client params、server params),就用 ecdhe 演算法一陣算,算出了乙個新的東西,叫「pre-master」,其實也是乙個隨機數。
現在客戶端和伺服器手裡有了三個隨機數:client random、server random 和 pre-master。用這三個作為原始材料,就可以生成用於加密會 話的主金鑰,叫「master secret」。而黑客因為拿不到「pre-master」,所以也就得不到主金鑰。
為什麼非得這麼麻煩,非要三個隨機數呢?
這就必須說 tls 的設計者考慮得非常周到了,他們不信任客戶端或伺服器偽隨機數的可靠性,為了保證真正的「完全隨機」「不可**」,把三個不可靠的隨機數混合起來,那麼「隨機」的程度就非常高了,足夠讓黑客難以猜測。
四、小結
1. https 協議會先與伺服器執行 tcp 握手,然後執行 tls 握手,才能建立安全連線;
2. 握手的目標是安全地交換對稱金鑰,需要三個隨機數,第三個隨機數「pre-master」必須加密傳輸,絕對不能讓黑客破解;
3. 「hello」訊息交換隨機數,「key exchange」訊息交換「pre-master」;
4. 「change cipher spec」之前傳輸的都是明文,之後都是對稱金鑰加密的密文。
至此,結束。
敏捷始於客戶
每個失敗的專案了都可以找這個藉口 專案周期短 需求變化快 人員有限。需求 工期是由客戶確定的。作為客戶來講,他不可能去合理評價給定的需求是否可以在某個時間內能夠完成,至於投入多少人那更是開發方自己的問題。開發方對客戶做出了承諾就要兌現承諾,否則就不要承諾,既然承諾了,就沒有理由再去抱怨工期短 需求變...
敏捷始於客戶
每個失敗的專案了都可以找這個藉口 專案周期短 需求變化快 人員有限 需求 工期 是由客戶確定的。作為客戶來講,他不可能去合理評價給定的需求是否可以在某個時間內能夠完成,至於投入多少人那更是開發方自己的問題。開發方對客戶做出了 承諾就要兌現承諾 否則就不要承諾,既然承諾了,就沒有理由再去抱怨工期短 需...
天下難事始於易,天下大事始於細。
質量保證的本質是什麼?今天聽得領導一番話,又有更高的感悟。什麼是qa?通常理解的qa最低乙個層次是按照檢查單,檢查規範流程,再高乙個層次是對業務有一定的認識的人對目前專案中存在問題提出自己的方案。最高層次,更有qa總監,是站在公司角度,把握流程規範,制定質量目標。但是今天領導對我說的又是另外一重含義...