1、介紹
TLS [RFC5246]允許客戶端或服務器啓動重新協商 - 建立新的加密參數的新握手。 不幸的是,雖然使用由原始握手建立的加密參數來執行新的握手,但是兩者之間沒有加密綁定。 這將爲攻擊者創造機會,攻擊者可以攔截客戶端的傳輸層連接,將自己的流量作爲前綴注入客戶端與服務器的交互。 這種攻擊的一種形式[Ray09]如下圖所示:
Client Attacker Server
------ ------- ------
<------------ Handshake ---------->
<======== Initial Traffic ========>
<-------------------------- Handshake ============================>
<======================== Client Traffic =========================>
要開始攻擊,攻擊者與服務器形成TLS連接(可能是響應於客戶端初始攔截的連接)。然後他將所選的任何流量發送到服務器。這可能涉及在應用層的多個請求和響應,或者可能僅僅是旨在在客戶端數據前綴的部分應用層請求。此流量顯示爲==表示已加密。然後他允許客戶端的TLS握手繼續服務器。握手對攻擊者來說是清楚的,但是通過攻擊者與服務器的TLS連接進行加密。握手完成後,客戶端通過新建立的安全參數與服務器通信。攻擊者無法讀取此流量,但服務器認爲來往於攻擊者的初始流量與客戶端的流量相同。3、安全協商定義
客戶端和服務器都需要爲每個TLS連接狀態存儲三個附加值(參見RFC 5246,第6.1節)。 請注意,這些值特定於連接(不是TLS會話緩存條目)。
- 一個“secure_renegotiation”標誌,指示安全重新協商是否用於此連接。
- “client_verify_data”:來自客戶端在緊接之前的握手中發送的Finished消息的verify_data。 對於當前定義的TLS版本和密碼套件,這將是一個12字節的值; 對於SSLv3,這將是一個36字節的值。
- “server_verify_data”:來自服務器在緊接之前的握手中發送的Finished消息的verify_data。
擴展定義:
"renegotiation_info" (withextension type 0xff01)
struct {
opaque renegotiated_connection<0..255>;
} RenegotiationInfo;
- 如果這是連接的初始握手,那麼ClientHello和ServerHello中的“renegotiated_connection”字段的長度都爲零。 因此,擴展的整個編碼是ff 01 00 01 00.前兩個八位字節表示擴展類型,第三和第四個八位字節是擴展本身的長度,最後八位字節表示“重新協商連接”字段的零長度字節。
- 對於重新協商的ClientHellos,該字段包含3.1節中指定的“client_verify_data”。
- 對於正在重新協商的ServerHellos,此字段包含client_verify_data和server_verify_data的並置。 對於TLS的當前版本,這將是一個24字節的值(對於SSLv3,它將是一個72字節的值)。
重新協商保護請求 SCSV
SSLv3和TLS 1.0 / TLS 1.1規範都要求實現忽略ClientHello之後的數據(即擴展),如果他們不瞭解它。但是,在這種情況下,一些SSLv3和TLS 1.0的實現方式不正確地失敗了握手。這意味着提供“renegotiation_info”擴展名的客戶端可能會遇到握手失敗。爲了增強與這些服務器的兼容性,本文檔通過特殊的信令密碼套件值(SCSV)“TLS_EMPTY_RENEGOTIATION_INFO_SCSV”定義了第二個信令機制,代碼點爲{0x00,0xFF}。該SCSV不是真正的密碼套件(它不對應於任何有效的算法集合),並且無法協商。相反,它具有與空的“renegotiation_info”擴展名相同的語義,如以下部分所述。因爲SSLv3和TLS實現可靠地忽略未知的密碼套件,所以可以將SCSV安全地發送到任何服務器。 SCSV也可以包含在SSLv2向後兼容的CLIENT-HELLO中(參見[RFC5246]的附錄E.2)。注意:根本不支持重新協商的最小客戶端可以在所有初始握手中簡單地使用SCSV。以下部分中的規則將導致任何兼容服務器在看到此類客戶重新協商的明顯嘗試時中止握手。
以下針對全連接和會話複用連接:
客戶端行爲:
初始化握手:
- 客戶端必須在ClientHello中包含一個空的“renegotiation_info”擴展或TLS_EMPTY_RENEGOTIATION_INFO_SCSV信令加密套件值。 不推薦同時包括這兩個。
- 收到ServerHello後,客戶端必須檢查是否包含“renegotiation_info”擴展名:
- 如果擴展名不存在,則服務器不支持安全重新協商; 將secure_renegotiation標誌設置爲FALSE。 在這種情況下,有些客戶可能希望終止握手而不是繼續; 參見第4.1節討論。
- 如果擴展名存在,請將secure_renegotiation標誌設置爲TRUE。 客戶端必須驗證“renegotiated_connection”字段的長度爲零,如果不是,則必須中止握手(通過發送致命的handshake_failure警報)。
- 握手完成後,客戶端需要保存client_verify_data和server_verify_data值以備將來使用。
安全重新協商:
如果連接的“secure_renegotiation”標誌設置爲TRUE(如果設置爲FALSE,請參見第4.2節),則此文本適用。
- 客戶端必須在ClientHello中包含“renegotiation_info”擴展,其中包含已保存的client_verify_data。 不得包括SCSV。
- 當接收到ServerHello時,客戶端必須驗證是否存在“renegotiation_info”擴展名; 如果不是,客戶必須中止握手。
- 客戶端必須驗證“renegotiated_connection”字段的前半部分是否等於保存的client_verify_data值,而後半部分是否等於保存的server_verify_data值。 如果不是,客戶必須中止握手。
- 握手完成後,客戶端需要保存新的client_verify_data和server_verify_data值。
服務器行爲:
初始化握手:
- 當接收到ClientHello時,服務器必須檢查它是否包含TLS_EMPTY_RENEGOTIATION_INFO_SCSV。如果是,請將secure_renegotiation標誌設置爲TRUE。
- 服務器必須檢查ClientHello中是否包含“renegotiation_info”擴展名。如果擴展名存在,請將secure_renegotiation標誌設置爲TRUE。服務器必須驗證“renegotiated_connection”字段的長度爲零,如果不是,請務必中止握手。
- 如果不包含TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV和“renegotiation_info”擴展名,請將secure_renegotiation標誌設置爲FALSE。在這種情況下,一些服務器可能希望終止握手而不是繼續;見第4.3節討論。
- 如果secure_renegotiation標誌設置爲TRUE,服務器必須在ServerHello消息中包含一個空的“renegotiation_info”擴展。
- 握手完成後,服務器需要保存client_verify_data和server_verify_data值以備將來使用。
安全重新協商:
如果連接的“secure_renegotiation”標誌設置爲TRUE(如果設置爲FALSE,請參見第4.4節),則適用此文本。
- 當接收到ClientHello時,服務器必須確認它不包含TLS_EMPTY_RENEGOTIATION_INFO_SCSV。 如果SCSV存在,服務器務必中止握手。
- 服務器必須驗證是否存在“renegotiation_info”擴展名; 如果不是,服務器務必中止握手。
- 服務器必須驗證“renegotiated_connection”字段的值等於保存的client_verify_data值; 如果不是,服務器務必中止握手。
- 服務器必須包含一個“renegotiation_info”擴展,其中包含ServerHello中保存的client_verify_data和server_verify_data。
- 握手完成後,服務器需要保存新的client_verify_data和server_verify_data值。