為什麼瀏覽器一直沒有默認啟用對 TLS 1.3 的支持
面對日益猖獗的黑客攻擊,許多沿用多年的網路安全標準也面臨著被替換或更新的命運。TLS是目前網路通信中應用最廣泛的密碼協議,TLS1.2是目前最常用的TLS版本,主要用於保護通過HTTPs傳輸的信息,為各種應用提供安全的通信信道,比如電子貨幣交易、郵件傳輸、VPN以及手機安卓應用等等。不過由於漏洞過多,且TLS的應用規模過於龐大,不斷地在大規模的應用中修修補補顯然達不到很好的防禦效果。
除此之外,交互雙方必須運行複雜的TLS握手協議才能開始傳輸信息,很多情況下我們希望在握手輪數和握手延遲方面可以有更多的選擇。出於以上以及其他種種因素的考慮,IETF從2014年就著手制定TLS 1.3。TLS 1.3延續了TLS 1.0、1.1和1.2的名稱,這說明它是之前版本的升級,TLS協議的大致框架並未發生本質改變。不過,TLS 1.3是TLS標準更新過程中變動最大的一次,除了對運行過程中的若干問題如密碼套件的選擇、密鑰的計算方式、握手消息的發送方式等做了更改之外,TLS 1.3還增加了新的握手模式,以滿足不同應用場景的需求。
升級安全協議所面對的困難
在像互聯網一樣複雜的生態系統中升級安全協議是困難的,你需要更新客戶端和伺服器,並確保它們連接起來都能繼續正常工作。2016年,Cloudflare是第一個在伺服器端默認支持TLS 1.3的供應商。自從Cloudflare的TLS 1.3發布以來,已經有一年多的時間了,但是仍然沒有一個主流的瀏覽器默認啟用TLS 1.3。
其主要的原因是因為中間件(middlebox):網路設備,該設備會被用於監視並攔截企業環境和移動網路中的HTTPS流量。但是,簡單地把責任歸咎於網路設備供應商是不客觀的的。更深層次的事實是,TLS 1.3最初的設計沒有考慮到互聯網應用的飛速發展。本文,我會構建了一個工具來幫助檢查你的網路是否與TLS 1.3兼容。
TLS的演化過程
傳輸層安全協議TLS是支持使用HTTPS進行安全Web瀏覽的重要手段,在20世紀90年代後期,TLS協議從較早的協議,即安全套接字層(SSL)改編而來。TLS目前有三個版本:1.0,1.1和1.2。該協議是非常靈活的,可以隨著時間的推移以不同的方式演變。較小的更改可以被合併為「擴展」(例如OCSP和證書透明度),而更大和更基本的更改通常需要新版本。TLS 1.3是迄今為止協議歷史上最大的變化,徹底修改了加密技術,並引入了像0-RTT這樣的特性。
並非所有的客戶端和伺服器都支持相同版本的TLS,因此不可能升級協議,因此大多數都同時支持多個版本。為了就連接的通用版本達成一致,客戶端和伺服器會進行協商。TLS版本的協商非常簡單。客戶端會通知伺服器它支持的協議的最新版本,伺服器則會回復它們都支持的協議的最新版本。
使用TLS連接到伺服器時,客戶端會在連接開始時發送其支持的最高版本:
(3, 3) server
一個理解相同版本的伺服器可以以相同的版本位元組開始回復:
(3, 3) serverclient (3, 3)
如果伺服器只知道該協議的舊版本,則可以使用舊版本進行回復。例如,如果伺服器只說TLS 1.0,則可以回復:
(3, 3) serverclient (3, 1)
如果客戶端支持伺服器返回的版本,則他們就可以繼續使用該版本的TLS並建立安全連接。如果客戶端和伺服器不共享通用版本,則連接失敗。
這次協商的目的是為了與未來版本兼容,如果客戶端發送的版本高於伺服器支持的版本,伺服器應該仍然能夠回復伺服器支持的任何版本。例如,如果客戶端發送(3,8)到TLS 1.2的伺服器,它應該只回復(3,3),握手將繼續作為TLS 1.2。
雖然很簡單,但事實證明,並沒有正確地實現這一功能,從而導致的一連串事件,讓網路用戶面臨嚴重的安全漏洞威脅。
poodle漏洞的出現和不安全的降級
TLS的最後一次大升級是引入了TLS 1.2,在瀏覽器中部署TLS 1.2的過程中,安全人員發現一些TLS 1.0伺服器沒有正確實現版本協商。當客戶端連接到TLS 1.2的TLS連接廣告支持時,有故障的伺服器將斷開連接,而不是協商他們理解的TLS版本(如TLS 1.0)。
瀏覽器有三個選項來處理這種情況:
1.啟用TLS 1.2,並關閉一些網站;
2.延遲TLS 1.2的部署,直到這些伺服器被修復;
3.如果連接失敗,則重試舊版本的TLS。
一般情況下,用戶認為,瀏覽器更新後,並不會影響網站的運行。由於目前協商不當的伺服器數量太多,所以選項3是唯一可行的選擇。
為了啟用TLS 1.2並保持用戶滿意,大多數瀏覽器實現了所謂的「不安全的降級(insecure downgrade)」。當連接到站點時遇到連接失敗時,他們將再次嘗試使用TLS 1.1,然後使用TLS 1.0,如果失敗,則使用SSLv3。這種降級邏輯雖然讓這些損壞的伺服器暫時看起來被「修復」,其實只是積壓了問題而已。
之所以,不安全的降級會被稱為不安全,是因為客戶端降級是由特定類型的網路故障觸發的,可能很容易被欺騙。從客戶的角度來看,無法判斷這個故障是由伺服器故障還是由正好處於連接網路路徑上的攻擊者造成的。這意味著網路攻擊者可以注入假的網路故障,並欺騙客戶端連接到SSLv3的伺服器,即使兩者都支持更新的協議。此時,SSLv3看起來還沒有嚴重的公開漏洞,不過,poodle漏洞的出現改變了這個看法。
2014年,POODLE(Padding Oracle On Downgraded Legacy Encryption)漏洞曾影響了使用最廣泛的加密標準——SSL v3.0,攻擊者可以利用該漏洞發動中間人攻擊攔截用戶瀏覽器和HTTPS站點的流量,然後竊取用戶的敏感信息,如用戶認證的cookies信息、賬號信息等。
由於TLS 1.0在客戶端和伺服器上都被廣泛部署,網路上很少有連接使用SSLv3,理論上,這應該保證它們的安全。然而,如果雙方都支持的話(大部分都是這樣),這種不安全的降級特點使得攻擊者可以將任何連接降級到SSLv3,從而形成一個大漏洞。
修復POODLE以及刪除不安全的降級所帶來的啟發
POODLE的修復過程如下:
1.禁用客戶端或伺服器上的SSLv3;
2.啟用稱為SCSV的新的TLS功能。
在POODLE漏洞發生的前的幾個月,SCSV就由BodoM?ller和Adam Langley提出。簡而言之,如果由於網路錯誤而重試,客戶端就會通過SCSV將名為「downgrade canary」的指標添加到客戶端hello消息中。如果伺服器支持比在客戶端hello中發布的版本更新的版本,並且看到這個「downgrade canary」指標,它可以假定降級攻擊正在發生並關閉連接。這是一個很好的功能,但它是個可選項,需要更新客戶端和伺服器。
刪除了瀏覽器對SSLv3的支持,除了影響一些只用SSLv3的網站之外,幾乎沒有什麼影響。使用舊瀏覽器的用戶必須依賴禁用SSLv3的Web伺服器, Cloudflare可以立即為客戶做到了這一點,大多數網站也是如此,但即使在2017年末,SSL Pulse測量的網站中仍有超過10%仍然支持SSLv3。
關閉SSLv3對於POODLE來說是一個可行的解決方案,因為SSLv3對於互聯網來說並不重要。這就產生了一個問題:如果TLS 1.0存在嚴重漏洞,會發生什麼? 目前,TLS 1.0的使用仍然是非常廣泛,在瀏覽器中關閉它將影響大約10%的網路用戶。而且,儘管SCSV是不安全降級的一個很好的解決方案,但許多伺服器還是不支持它。
TLS 1.3的介紹
為未來的兼容性設計協議是困難的,如果沒有反饋機制,很容易出錯。TLS版本協商雖然很簡單,但實際上是協議設計的一個反面模式。在TLS 1.2部署的時候,圍繞著設計一個雄心勃勃的新版TLS的討論正在開始。它將被稱為TLS 1.3,版本號自然選為3.4(或(3,4))。到2016年年中,TLS 1.3草案已經經歷了15次迭代,基本確定了版本號和協商。在這一點上,瀏覽器已經消除了不安全的可能。假設無法正確進行TLS版本協商的伺服器已經學習了POODLE的教訓,並最終正確地實現了版本協商。事實證明,情況並非如此。漏洞再次發生。
當與3.4版本的客戶問好時,很大一部分支持TLS 1.2的伺服器會斷開連接,而不是回復3.3。 經過實際測試證實,TLS 1.3的失敗率非常高,在許多測量中超過3%。這與升級到TLS 1.2時所面臨的情況完全相同。
這個意想不到的挫折給參與協議設計的人們帶來了很大打擊,顯然,照此下去,瀏覽者不希望重新啟用這種不安全的降級。但是,如果沒有降級,使用TLS 1.3將會為用戶提高3%的上網風險。
有人曾建議過如下的解決方法:就是使第一個TLS 1.3消息(客戶問候)看起來像TLS 1.2。客戶端的版本號被重新改回(3,3),並引入了一個新的「版本」擴展,其中包含了受支持版本的列表。如果支持TLS 1.3和(3,3),則伺服器將返回以(3,4)開始的伺服器hello,否則返回前面的值。 所以,TLS 1.3草案16就包含了這個新的和「改進的」協議協商邏輯。
大部分伺服器都可以接受這個變化,並且很容易回到TLS 1.2,從而忽略了新的擴展。但它不僅會影響客戶端和伺服器,還會影響網路上與協議交互的所有內容。
現實世界充滿了中間件
我曾經測量了瀏覽器和Web伺服器之間的檢測軟體或硬體實際攔截和解密了多少「安全」HTTPS連接。還有一些被動的檢查中間件解析TLS,並根據可見數據阻止或轉移連接,如使用來自TLS連接的主機名信息(SNI)的ISP來阻止「禁止」網站。
為了檢查流量,這些網路設備需要實施部分或全部的TLS,每個支持TLS的新設備都引入了一個TLS實現。
在2017年2月,Chrome和Firefox都開始為其客戶提供TLS 1.3。結果出乎意料的糟糕。對於一些用戶來說,不管是什麼網站,都是TLS 1.2在工作,但TLS 1.3似乎消失了。
經過一番調查,發現一些廣泛部署的中間件,無論是攔截式還是被動式,都會造成連接失敗。
由於TLS在整個演變歷史中看起來大致相同,因此一些網路設備對協議如何隨著時間的推移作出了一個提前假設。當遇到違反這些假設的新版本時,這些設備會出現各種方式的故障。
TLS 1.3中更改的TLS的一些功能僅僅是表面上的,自SSLv3被刪除後,協議中的ChangeCipherSpec,session_id和壓縮欄位就都被刪除。這些都被認為是TLS對這些中間件的一些基本特徵,如果刪除它們就會導致連接失敗。
如果一個協議在足夠長的時間內使用了類似的格式,那麼圍繞該協議構建工具的人就會假定這種格式是不變的。這通常不是開發人員有意的選擇,而是在實踐中使用協議的意外結果。網路設備的開發人員很可能不會了解互聯網上使用的每一種協議,所以他們經常會選擇測試他們在網上看到的常用協議。
如何讓TLS 1.3普及
2017年11月在新加坡舉行的IETF會議上,TLS 1.3提出了一個新的改變來幫助解決這個問題。這些變化是基於來自Facebook的Kyle Nekritz的想法,即使TLS 1.3看起來像TLS 1.2到中間件。這個改變重新引入了被刪除的協議中的很多部分,比如,session_id,ChangeCipherSpec和一個空的壓縮欄位,這就使得TLS1.3看起來像TLS1.2一樣,這對於中間件很重要。
這些變化的幾個迭代是由BoringSSL開發的,並已在Chrome上測試了幾個月。 Facebook也進行了一些類似的測試,且兩個團隊的發現都差不多。
Chrome測試的連接成功率:
TLS 1.2 - 98.6%
Experimental changes (PR 1091 on Github) - 98.8%
Firefox測試的連接成功率:
TLS 1.2 - 98.42%
Experimental changes (PR 1091 on Github) - 98.37%
這些測試表明,這些變化可以將TLS 1.3修改為與中間件兼容。這就導致了草案16的產生,在草案中,標準的研發者將版本協商轉移到了擴展。作為客戶端和伺服器之間的中介,這樣中間件也關心伺服器hello消息。
去年,Adam Langley寫了一篇關於加密協議設計的博客文章,其內容與本文相似,有興趣的讀者可以看一看。
David Benjamin提出了一種方法來保持TLS中最重要的關節,他對GRE的GREASE提案是為了在協議應該容忍新值的情況下拋出隨機值。如果流行的實現在真實的部署中插入未知的密碼、擴展和版本,那麼實現者將被迫正確地處理它們。在互聯網上,GREASE就像WD-40一樣。
有一點需要注意的是,GREASE旨在防止伺服器僵化,而不是中間件,所以在TLS中仍有可能出現更多類型的GREASE。
即使有了GREASE,一些伺服器直到2017年12月才被發現無法支持TLS 1.3。GREASE只識別那些不能接受未知擴展的伺服器,但有些伺服器可能仍然不能容忍特定的擴展id。例如,RSA的BSAFE庫使用了擴展id 40作為一個名為「extended_random」的實驗性擴展,與一個理論上的美國國家安全局後門聯繫在一起。擴展id 40恰好是TLS 1.3密鑰共享的擴展id。David Benjamin說,一些印表機仍在使用該庫,這導致他們無法忍受TLS 1.3。Matthew Green對這個兼容性問題進行了詳細的描述。
Google和Facebook一直在做自己的測量。這些實驗很難執行,因為開發人員需要將協議變體添加到瀏覽器中,在幾個月的發布周期里測試,讓用戶有充足的時間發現問題。Cloudflare現在支持最新與middlebox兼容的TLS 1.3草案版本(草案22),相信,在實測中,Cloudflare總有機會找到一個與這個版本不兼容的中間件。
※公有雲數據安全如何產品化?
※PowerStager工具分析
TAG:嘶吼RoarTalk |