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值。