QUIC加密協議

weixin_34006468發表於2017-05-09

摘要

QUIC加密協議是QUIC的一部分,它為連線提供了傳輸安全性。QUIC加密協議是 註定要消亡的。未來它將由TLS 1.3替代,但在TLS 1.3 最終啟用之前QUIC需要一個加密協議。

藉助於當前的QUIC加密協議,當客戶端已經快取了關於伺服器的資訊時,它可以無需往返就建立一個加密的連線。TLS,相反地,至少需要兩次往返(算上TCP的3次握手)。QUIC握手應該比普通的TLS 握手(2048-bit RSA)高效大約5倍,而且安全等級更高。

源地址欺騙

Internet上的協議很少能在無需至少一個初始化往返的情況下就可以工作的。大多數協議由於TCP而需要一個往返,基於TLS的協議在應用資料可以傳輸前,需要至少額外的一個或更多往返。

這些往返都交換nonces:在TCP的情況下是序列號(或SYN cookies),在TLS的情況下是密碼學隨機值(client_random 和 server_random)。TCP nonce防止IP地址欺騙,而TLS nonce防止重放攻擊。任何想要尋求減少往返的協議都不得不以某種方式解決這兩個問題。

作為一個反例,DNS是一個沒有任何初始化往返的協議,因此它不得不自己處理IP地址欺騙和重放攻擊。DNS簡單地忽略IP地址欺騙,並因此使映象DDoS攻擊成為一個真正的問題。對於重放的保護,DNSSEC依賴時鐘同步和短時的簽名。根據設計,這允許有限時間內的重放,由於那與DNS的快取語義相互協調。但那不是重放保護的嚴格形式,因為重放是被允許的。

在QUIC中,我們分開處理這兩個問題。

IP地址欺騙問題通過給客戶端分配一個,即期的,“源地址token”來處理。從客戶端的視角來看,這是透明的位元組串。從伺服器的視角來看,它是一個認證的加密塊(比如 AES-GCM),其中包含,至少,客戶端的IP地址,和一個伺服器的時間戳。伺服器將只為給定的IP給那個IP傳送一個源地址token。客戶端收到token被視為對IP地址擁有所有權的證明,與TCP序列號的接收 所採用的方式一樣。

客戶端可以在未來的請求中包含源地址token以證明對它們的源IP地址的所有權。如果客戶端的IP地址變了,則token也過時了,或者客戶端沒有token,則伺服器可以拒絕連線,並返回一個新的token給客戶端。但是如果客戶端的IP地址保持不變,則它可以複用源地址token以避免獲取一個新token所需的網路往返。

Token的生命週期主要與伺服器有關,但由於源地址token是不記名token,它們可能被盜取並被複用以繞過基於IP地址的限制。(儘管攻擊者將無法收到響應。)源地址token還可以被收集,並可能在IP地址的所有權發生變化之後使用(比如,在DHCP池中)。簡少token的壽命,以減少在無需額外往返的情況下處理的請求的數量為代價來改善這兩個問題。

源地址token,不像TCP序列號的交換,不要求源表現出連續的接收傳送到源IP地址的分組的能力。這允許源地址token被用於持續地請求來自於伺服器的業務,即使下行鏈路已經飽和,其丟包率足夠高以至於不能建立TCP連線。這種 “自 DOS” 攻擊可用於 DOS 相同下行鏈路中的其他使用者。

然後,我們注意到 類似的技巧實際上可能用於TCP,因此QUIC並沒有在這方面明顯地使事情變得更糟。確實,一旦連線建立好,QUIC在包中包含了一個熵位,並要求接收者傳送它們聲稱已經收到的熵的雜湊值 - 從而解決TCP的問題。

為了最小化延遲,伺服器可以動態地決定放鬆源地址限制。可以想象伺服器跟蹤來自不同IP地址的請求的數量,並且只有當“未請求”連線的數量超過全域性或某個IP範圍的限制時,才需要源地址token。這可能是有效的,但不清楚這是否是全球穩定的。如果大量的QUIC伺服器實現了這種策略,則大量的映象DDoS攻擊可以在它們之間分割,使得任何一臺伺服器都不會達到攻擊閾值。

重放攻擊

在TLS中,每一方都生成一個隨機數,通過強制它們在金鑰中包含(假定在所有時間唯一)該值,用於確保另一方是新的。沒有往返,客戶端仍然可以包括一個隨機值以確保伺服器是新的,但伺服器沒有機會為客戶端這樣做。

在沒有來自伺服器的輸入的情況下提供重放保護基本上是非常昂貴的。它需要伺服器端的一致狀態。儘管如果伺服器是單臺機器的話這是合理的,但現代的網站都遍佈全世界。

因此,QUIC在伺服器的第一次應答之前不為客戶端的資料提供重放保護。這依賴應用去確保這樣的資訊在被攻擊者重放時是安全的。比如,在Chrome中,只有GET請求在握手確認前傳送。

握手開銷

在TLS中,伺服器基於客戶端廣告的它們支援的引數為每個連線選擇連線引數。在QUIC中,伺服器的首選項完全是列舉的和靜態的。它們與Diffie-Hellman公共值一起捆綁到一個“伺服器配置”中。這個伺服器配置含有一個過期時間,並由伺服器的私鑰簽名。由於伺服器配置是靜態的,因而不是每個連線都需要簽名操作,而是單個簽名足以滿足許多連線。

使用Diffie-Hellman可用的連線金鑰。伺服器的 Diffie-Hellman 值在伺服器配置中發現,客戶端在它的第一個握手訊息中提供。由於伺服器配置必須保留一段時間,以允許0-RTT握手,這給連線的前向安全性設定了上限。既然伺服器記錄了伺服器配置的 Diffie-Hellman 金鑰,則如果它們洩漏的話用那個伺服器配置加密的資料可能被解密。

這樣QUIC提供了兩個層面的保密:來自於客戶端的初始資料使用伺服器的伺服器配置中的 Diffie-Hellman 值加密,這可能持續幾天。一接收到連線,伺服器就用一個 短暫Diffie-Hellman 值來響應,然後連線被重新計算金鑰。

(相對於前向安全的TLS連線,這可能似乎提供更少的前向安全性。然而,為了避免往返,通常在大規模部署中都會啟用TLS Session Tickets。SessionTicket 金鑰足以解密連線,但為了恢復的有效性,它必須保持合理的時間段 - 通常是幾天。SessionTicket金鑰和伺服器配置金鑰類似,且有效的安全性實際上比QUIC要高,因為它的前向安全模式更優越。)

單個連線是通常的前向安全性的範圍,但是用於一個單獨的連線的短暫的金鑰,和在 60 秒內用於所有連線的金鑰的安全性的差異是微不足道的。因此我們可以在小的時間跨度中將伺服器的 Diffie-Hellman 金鑰生成分攤在所有的連線上。

(由於伺服器配置和 Diffie-Hellman 私有值是伺服器為了處理QUIC連線所需的所有東西,證書的私鑰從不需要放在伺服器上。相反,短期證書的一種形式可以通過簽署短期伺服器配置並僅安裝在伺服器上來實現。)

如果我們設 S 是一個金鑰操作(比如RSA解密),P 是一個公鑰操作(比如 RSA加密),F 是一個 Diffie-Hellman,定點的,標量乘法,而且 A 是一個任意點,標量乘法則:

  1. TLS,非前向安全握手:伺服器,1S (1100µs);客戶端,1P (34µs)。
  2. TLS,前向安全握手:伺服器,1S + 1F + 1A (1301µs);客戶端,1P + 1F + 1A (235µs)。
  3. QUIC:伺服器,2A (100µs);客戶端,1F + 2A + 1P (184µs)。

(客戶端驗證證書鏈的操作沒有包含在內。)

如果我們為這些中的每個選擇公共基元(RSA 2048用於公共和私有操作,ECDH P-256用於TLS前向安全,Curve25519用於QUIC的),那麼我們獲得在i7-3770S上的括號中的示例時間。如果 QUIC使用 P-256,則伺服器時間將是 300µs,客戶端將是385µs,所以相當多的收益來自於更好的基元。

粗略統計TLS會話恢復率大約為 50%,但 QUIC 不包含顯式地會話恢復。然而,它可以在不在協議中支援恢復的情況下獲得許多恢復的益處,通過使客戶端和伺服器維護一個 Diffie-Hellman 結果的快取。只要客戶端沒有旋轉其臨時金鑰,這個可選的快取就可以消除使用同一伺服器多次握手的計算負擔。如果我們假設TLS的恢復率為 50%,並假設QUIC快取不做任何事,則相對於簡介中提到的TLS,我們獲得大約 5x 的速度提升。

Wire協議

QUIC是一個資料包協議,一旦金鑰建立,則每個資料包的完整載荷(在UDP層之上)都是被認證和加密的。底層的資料包協議為加密層提供了可靠的傳送方式,任意大小的訊息。這些訊息具有一個統一的,鍵值格式。

鍵是 32-bit tags。這試圖在魔術數字登錄檔的粗暴和字串的冗長之間提供一個平衡。就Wire協議而言,這些是不透明的,32位的值,在本文中,tags 通常將是 EXMP。雖然它是一個字串,但是它只是值 0x504d5845 的助記符。該值,是小尾端的,是ASCII字串 E X M P。

如果 tag 是ASCII,但它少於四個字元,則就好像剩餘的字元是NUL。因此 EXP 對應於 0x505845。

如果 tag 值包含超出ASCII範圍的位元組,則它們將以十六進位制格式寫入,比如,504d5845。

除非另有說明,否則所有值都是小尾端的。

握手訊息的組成為:

  1. 訊息的標籤(tag)。
  2. 包含標籤值對數量的uint16。
  3. 傳送時的兩個值為零的填充位元組,接收時要被忽略。
  4. 一系列 uint32 標籤 和 uint32 結束偏移,每個標籤值對一個。標籤必須是嚴格地單調遞增的,並且結束偏移必須是單調的非遞減。結束偏移給出了偏移量,從值資料的開始處算起,到超出那個標籤的資料的結尾處一個位元組的位置結束。(因此最後一個標記的結束偏移包含值資料的長度)。
  5. 值資料,無填充連線。

標籤值格式允許在只有一小部分資料被驗證後對標籤進行有效的二分搜尋。標籤嚴格單調的要求也消除了關於重複標籤的任何歧義。

儘管當前 32 位的長度超出了需要,16位長度存在不足以處理更大的後量子值的風險。

任何訊息可以包含一個填充 (PAD) 標記。這些可以用來打敗流量分析。此外,我們可以為客戶端的 hellos 定義一個全域性的最小大小以限制放大攻擊。小於最小值的客戶端hello將需要PAD標記來彌補差異。

客戶端握手

客戶端握手的流程如圖1。概念上來說,QUIC中的所有握手都是 0-RTT的,只是它們中的一些會失敗,需要重試。

圖 1. 客戶端握手流程

為了執行0-RTT握手,客戶端需要具有已被驗證為可信的伺服器配置。最初,我們假設客戶端不知道任何關於伺服器的東西,因此,在可以嘗試握手之前,客戶端將傳送“inchoate” 客戶端 hello 訊息以從伺服器引出伺服器配置和真實性證明。在客戶端收到其需要的所有資訊前,可能會有幾輪 inchoate 客戶端 hellos,因為伺服器可能不願意向未經驗證的IP地址傳送大量的真實性證明。

Client hello 具有訊息標記CHLO,並且以其初始形式包含以下標記/值對:

  • SNI Server Name Indication (伺服器名稱指示)(可選的):伺服器的完全限定DNS名稱,規範化為小寫,沒有尾隨週期。國際化的域名需要被編碼為 RFC 5890 中定義的 A-labels。SNI 標籤的值不能是IP地址字面量。
  • STK 源地址令牌 (Source-address token)(可選的):伺服器先前提供的源地址令牌(如果有)。
  • PDMD 證明需求 (Proof demand):描述客戶端可接受的證明型別的標籤列表,按照優先順序。目前只定義了X509。
  • CCS 公共證書集 (Common certificate sets)(可選的):一系列 64 位,** FNV-1a** 雜湊的客戶端擁有的公共證書集 。(參考關於證書壓縮的小節。)
  • VER 版本:單個標籤,反映客戶端在第一個資料傳輸中的每個QUIC資料包中通告的協議版本。如果發生了版本協商,則這個欄位被設為客戶端使用的第一個版本。如果包中的版本不等於標籤中的版本,則伺服器需要驗證伺服器不支援標籤中的版本以防禦降級攻擊。
  • XLCT 客戶端期望伺服器使用的葉證書的64位,** FNV-1a** 雜湊值。證書的完整內容將被加進 HKDF。如果存在快取的證書,則首個這樣的條目應與此欄位的值一致。

(QUIC的其它部分可以定義客戶端和伺服器的 hellos 中包含的額外標籤。比如,流的最大個數,擁塞控制引數等等。然而,那些標籤不在本規範中定義。)

作為對客戶端 hello 的響應,伺服器將傳送一個拒絕訊息,或一個伺服器 hello。伺服器 hello 表示一個成功的握手,並且永遠不會從初始客戶端 hello 產生,因為它不包含足夠的資訊來執行握手。拒絕訊息包含客戶端可用以在後面執行更好的握手的資訊。

拒絕訊息具有 REJ 標籤,且包含如下的標 籤/值 對:

  • SCFG 伺服器配置(Server config)(可選的):包含了伺服器的序列化的配置的訊息。(在下面描述。)
  • STK 源地址令牌 (Source-address token)(可選的):客戶端應該在未來的客戶端 hello 訊息中回顯的透明位元組串。
  • SNO 伺服器隨機數 (Server nonce)(可選的):伺服器可以設定一個隨機數,客戶端應該在任何未來的(完整的)客戶端 hello 訊息中回顯此隨機數。這允許伺服器在沒有觸發暫存器的情況下操作,而客戶端在時鐘偏斜的情況下連線。
  • STTL 伺服器配置有效的持續時間,以秒計,
  • ff545243 證書鏈(可選的):伺服器的證書鏈。(參考關於證書壓縮的小節。)
  • PROF 真實性證明(可選):在 X.509 的情況下,伺服器配置的葉子證書的公鑰簽名。當前這個簽名的格式由公鑰的型別固定:
RSA RSA-PSS-SHA256
ECDSA ECDSA-SHA256

簽名通過如下方式計算:

  1. 標籤 “QUIC server config signature”
  2. 下一個欄位中雜湊的32位長度的位元組數(即8)
  3. CHLO 的 SHA256 雜湊
  4. 一個 0x00 位元組
  5. 序列化的伺服器配置

儘管拒絕訊息的所有元素是可選的,但是伺服器必須允許客戶端進行。比如,如果客戶端不存在源地址令牌,且伺服器不希望傳送伺服器配置給一個未經驗證的 IP 地址,則伺服器必須以一個源地址令牌來響應以使客戶端接下來的握手嘗試更加成功。

一些標記以十六進位制而不是以ASCII符號指定。這是因為標籤被構造為使得它們將在訊息的開始或結束到來。回想一下,標記,作為數字,是以小尾端序寫入線上的。

包含熵的標籤被移動到訊息的開始,因為伺服器可能不維護狀態,因此可以處理重複的客戶端 hello 兩次。如果拒絕訊息分組丟失,並且熵欄位跨越分組邊界,則客戶端可能錯誤地組合它們。

大標記(到目前為止是證書鏈)被移動到訊息的結尾,使得它們不會延遲可能足夠的其它欄位的接收。

伺服器配置包含序列化的伺服器首選項,並採用具有標籤 SCFG 的握手訊息的形式。它包含如下的標 籤/值 對:

  • SCID 伺服器配置 ID:這個伺服器配置的透明的,16位元組識別符號。
  • KEXS 金鑰交換演算法:標記列表,以優先順序,指定了伺服器支援的金鑰交換演算法。定義了以下標記:
C255 Curve25519
P256 P-256
  • AEAD 驗證加密演算法:標記列表,以優先順序,指定了伺服器支援的 AEAD 基元。定義了以下標記:
AESG 具有 12 位元組標記和 IV 的AES-GCM。IV 的頭四個位元組取自於金鑰推導,而後 8 個則是分組序列號。
S20P Salsa20 with Poly1305。(暫時還沒有實施。)
  • PUBS 公共值的列表,24 位,小尾數長度字首,與 KEXS 相同的順序。P-256 公共值,如果有的話,被編碼為X9.62格式的未壓縮點。

  • ORBT 軌道(Orbit):一個8位元組的不透明值,用於標識觸發暫存器(殘留)。

  • Expiry 到期(Expiry):以 UNIX epoch 秒計數的伺服器配置 64 位到期時間。

  • VER 版本:伺服器支援的版本標記的列表。底層的 QUIC 包協議有版本協商。伺服器支援的版本是簽名的伺服器配置的映象,以確保沒有降級攻擊的發生。

一旦伺服器接收了伺服器配置,且已經認證了它並驗證了證書鏈和簽名,它可以通過傳送完整的 client hello 來執行一個不是設計為失敗的握手。完整 client hello 包含與初始 client hello 相同的標籤,加上幾個其他的:

  • SCID 伺服器配置 ID:客戶端使用的伺服器配置 ID。

  • AEAD 驗證加密:被使用的 AEAD 演算法的標籤。

  • KEXS 金鑰交換:被使用的金鑰交換演算法的標籤。

  • NONC 客戶端隨機數:由 4 位元組的時間戳(大尾端,UNIX epoch 秒),8 位元組的 伺服器軌道,和 20 位元組的隨機陣列成的 32 位元組數。

  • SNO 伺服器隨機數(可選的):回顯的伺服器隨機數,如果伺服器提供了的話。

  • PUBS 公共值:對於給定的金鑰交換演算法,客戶端的公共值。

  • CETV 客戶端加密標籤值(可選的):序列化訊息,以在 client hello 中指定的 AEAD 演算法加密,並且具有以下面 CETV 部分中指定的方式匯出的金鑰。此訊息將包含進一步的加密的標籤值對,指定客戶端證書,ChannelID 等。

傳送了完整的 client hello 之後,客戶端擁有用於連線的非前向安全金鑰,因為它可以計算來自伺服器配置的共享值和PUBS中的公共值。(有關金鑰推導的詳細資訊,請參見下文。)這些金鑰被稱為初始金鑰(而不是稍後的前向安全金鑰)且客戶端應該用這些金鑰加密未來的包。它還應該配置資料包處理以接受使用這些金鑰以鎖定方式加密的資料包:一旦已經接收到加密分組,則不應接受另外的未加密分組。

在此時,客戶端可以自由地開始向伺服器傳送應用程式資料。實際上,如果它希望實現0-RTT,則它必須在等待伺服器的答覆之前開始傳送。

資料的重傳發生在握手層下面的層,然而該層必須仍然知道加密的改變。新的分組必須使用初始金鑰來傳輸,但是如果 client hello 需要重傳,則必須以明文的方式重傳。分組傳送層必須知道哪個安全級別最初用於傳送任何給定分組,並且小心不要使用更高的安全級別,除非對端已經確認擁有這些金鑰(即通過使用該安全級別傳送分組)。

伺服器將接受或拒絕握手。伺服器拒絕 client hello 的情況下,它將傳送 REJ 訊息,並且使用初始金鑰傳送的所有分組必須被認為丟失並且需要在新的初始金鑰下重傳。因此,在 server hello 或 拒絕 待定時,客戶端應該限制未完成的資料量。

在理想的情況下,握手成功,伺服器返回一個 server hello 訊息。此訊息具有標記 SHLO,使用初始金鑰加密,除了為拒絕訊息定義的標記/值對之外,還包含以下標記/值對:

  • PUBS 客戶端用於金鑰交換演算法的臨時公共值。通過手中的臨時公共值,雙方都可以計算前向安全金鑰。(見關於金鑰推導的部分。)伺服器可以立即切換為使用前向安全金鑰傳送加密資料包。客戶端必須等待收 server hello。(注意:我們正在考慮讓伺服器等待,直到它在傳送任何自己之前接收到前向安全資料包。如果 server hello 資料包被丟棄,這避免了停頓。)

金鑰推導

金鑰材料由經過雜湊函式 SHA-256 的基於 HMAC 的金鑰匯出函式(HKDF)生成。HKDF(在 RFC 5869 中描述)使用 NIST SP 800-56C 中描述的已批准的兩步金鑰匯出過程。

第 1 步:HKDF 提取
金鑰協議的輸出(在Curve25519和P-256的情況下為32位元組)是預主金鑰,後者是HKDF-提取 函式的輸入金鑰材料(IKM)。鹽 輸入是客戶端隨機數,後跟伺服器隨機數(如果有的話)。HKDF-提取 輸出偽隨機金鑰(PRK),其是主金鑰。 如果使用SHA-256,主金鑰為32位元組長。

第 2 步:HKDF 擴充套件
PRK 輸入是主金鑰。info 輸入(上下文和應用程式特有資訊)是以下資料的級聯:

  1. 標籤 “QUIC key expansion”
  2. 一個 0x00 位元組
  3. 來自資料包層的連線的GUID。
  4. client hello 訊息
  5. 伺服器配置訊息
  6. DER 編碼的葉子證書的內容

金鑰材料按以下順序分配:

  1. 客戶端寫金鑰。
  2. 伺服器寫金鑰。
  3. 客戶端寫 IV。
  4. 伺服器寫 IV。

如果任何原語需要少於金鑰材料的整個位元組數,則丟棄最後一個位元組的剩餘部分。

當推導前向安全金鑰時,使用相同的輸入,除了info使用標籤“QUIC前向安全金鑰擴充套件 (QUIC forward secure key expansion)”。

當推導伺服器的初始金鑰時,它們必須是多樣化的,以確保伺服器能夠向HKDF提供熵。

第 1 步:HKDF 提取

伺服器寫金鑰加上來自找到的輪的伺服器寫IV的級聯是用於 HKDF-Extract 函式的輸入金鑰材料(IKM)。鹽輸入是多樣化隨機數。HKDF-Extract 輸出一個偽隨機金鑰(PRK),它是多樣化金鑰。如果使用 SHA-256 的話,多樣化金鑰是 32 位元組長的。

第 2 步:HKDF 擴充套件
PRK 輸入是多樣化金鑰。info 輸入(上下文和應用特有資訊)是標籤"QUIC 金鑰多樣化 (QUIC key diversification)"。

金鑰材料按以下順序分配:

  1. 伺服器寫金鑰。
  2. 伺服器寫 IV。

客戶端加密的標籤值

client hello 可能包含一個 CETV 標籤,以描述客戶端證書,ChannelIDs 和 client hello 中的其它非公有資料。(那與 TLS 相反,它以明文傳送客戶端證書。)

CETV 訊息以 client hello 中的 AEAD 序列化和加密。金鑰是以與連線的金鑰相同的方式推導的(參考上面的 金鑰推導),除了 info 使用標籤“QUIC CETV 塊(QUIC CETV block)”。推導中所用的 client hello 訊息是無 CETV 標記的 client hello。當隨後推導連線金鑰時,所使用的 client hello 將包含 CETV 標記。

AEAD 隨機數總是 0,它是安全的,這是因為只有一個訊息曾以該金鑰加密。

通過對 CETV 金鑰推導中所使用的 HKDF info 輸入簽名,來完成對客戶端證書和 ChannelID 兩者所需的私鑰的擁有。

CETV 訊息可以包含如下的標籤:

CIDK ChannelID 金鑰(ChannelID key)(可選的):一個 32位元組對,大尾端數字,一起描述一個 (x, y) 對。這是 P-256 曲線上的一個點和一個 ECDSA 公鑰。

CIDS ChannelID 簽名(ChannelID signature)(可選的):一個 32位元組對,大尾端數字,一起描述一個 HKDF 輸入的 ECDSA 簽名的 (r, s) 對。

證書壓縮

在 TLS 中,證書鏈是無壓縮傳輸的,並佔用了完整握手中的絕大多數字節。在 QUIC 中,我們希望能夠通過壓縮證書來避免一些往返。

證書鏈是一系列的證書,就這一節的目的而言,是透明的位元組串。葉子證書總是鏈中的第一個,且從不應該包含根 CA 證書。

當在一個拒絕訊息的 CRT\xFF 標籤中序列化一個證書鏈的時候,伺服器認為那些資訊客戶端已經有了。這些先驗知識可以來自於兩種方式:擁有一般中間證書,或者快取了之前與相同伺服器互動時的證書。

前者表示為 client hello 的 CCS 標籤中的一系列 64-bit FNV-1a 雜湊值。如果客戶端和伺服器共享了至少一個一般證書集合,則可以簡單地引用它們中存在的證書。

快取的證書表示 client hello 的 CCRT 標籤中的 64-bit FNV-1a 雜湊值。如果任何一張依然在證書鏈中,則它們可由雜湊值代替。

任何剩餘的證書以一個預共享的由前兩個方法指定的證書和取自於 Alexa top 5000 的證書中的字串組成的字典經 gzip 壓縮。

具體的表示方式被放置在拒絕訊息的CERT標籤中,並具有以下 TLS 表示風格中的 Cert 結構格式:

enum { end_of_list(0), compressed(1), cached(2), common(3) } EntryType;

struct {
  EntryType type;
  select (type) {
    case compressed:
      // nothing
    case cached:
      opaque hash[8];
    case common:
      opaque set_hash[8];
      uint32 index;
  }
} Entry;

struct {
  Entry entries[];
  uint32 uncompressed_length;
  opaque gzip_data[];
} Certs;

(回憶一下,QUIC 中的數字是小尾端的。)

entries 列表以一個型別為 end_of_list 的 Entry 結束,而不是
TLS 中常見的長度字首。gzip_data 擴充套件到值的末尾。

gzip,預共享字典包含型別為 compressed 或 cached 的證書,以相反的順序連線,其後是此處未提供的 ~1500 個位元組的公共子字串。

未來方向

  1. ChannelID 非常有可能從協議層中移除,相反,加密握手將產生可以在較高層簽名的通道繫結值。
  2. Trevor Perrin 已經指出,伺服器可以返回一個加密票證,其中包含客戶端可以在未來的連線中回顯給伺服器的 Hash (前向安全保密)。對於那些握手,這將節省一次 Diffie-Hellman 操作。
  3. 伺服器應該能夠向客戶端指示,它們應該在傳送應用資料之前等待直到前向安全金鑰建立。
  4. 為了避免 server hello 包造成的隊首阻塞,伺服器可以避免傳送前向安全資料,直到客戶端確認接收到 server hello。(比如:通過自身傳送前向安全包。)

感謝

多謝 Trevor Perrin, Ben Laurie 和 Emilia K�äsper 的有價值的反饋。

打賞

原文

相關文章