Appendix E. Backward Compatibility (向后兼容性)
本附录讨论TLS 1.2与早期版本的兼容性问题.
E.1. Compatibility with TLS 1.0/1.1 and SSL 3.0 (与TLS 1.0/1.1和SSL 3.0的兼容性)
由于存在新特性和一些结构性变化, TLS 1.2与TLS 1.1, TLS 1.0和SSL 3.0之间没有直接的互操作性. 然而, TLS 1.2包含了一种机制, 通过该机制TLS 1.2实现可以与早期版本协商.
E.1.1. 版本协商
TLS提供了一个内置的机制, 用于版本协商作为握手的一部分:
-
ClientHello中的版本:
- 客户端在ClientHello中指示它支持的最高版本
- 实现应该 (SHOULD) 在ClientHello中指示TLS 1.2 (版本 3)
-
ServerHello中的版本:
- 服务器选择它和客户端都支持的最高版本
- 如果服务器不支持客户端建议的版本, 它选择较低的版本
-
记录层版本:
- ClientHello记录的版本应该 (SHOULD) 设置为 1 (TLS 1.0) 以获得最大兼容性
- 后续记录使用协商的版本
E.1.2. 扩展
TLS 1.2引入了新的扩展和对现有扩展的更改:
- signature_algorithms扩展: TLS 1.2客户端必须 (MUST) 包含此扩展
- 旧版本的服务器将忽略不理解的扩展
E.1.3. 密码套件
某些密码套件特定于TLS 1.2:
- 使用SHA-256 PRF的密码套件
- 新的AEAD密码套件
当与早期版本协商时, 这些密码套件不应该 (SHOULD NOT) 在ClientHello中提供.
E.1.4. 实现建议
客户端实现应该 (SHOULD):
- 支持多个TLS版本
- 在ClientHello中公告最高支持的版本
- 准备好接受较低的版本
- 实现版本回退保护 (SCSV)
服务器实现应该 (SHOULD):
- 支持多个TLS版本以实现广泛兼容性
- 优先选择最高的协议版本
- 正确处理早期版本的ClientHello
示例协商流程:
客户端 (支持TLS 1.2, 1.1, 1.0)
-> ClientHello (version=3.3)
支持的版本: TLS 1.2, 1.1, 1.0
服务器 (仅支持TLS 1.1, 1.0)
<- ServerHello (version=3.2)
选择: TLS 1.1
连接使用TLS 1.1继续
E.2. Compatibility with SSL 2.0 (与SSL 2.0的兼容性)
SSL 2.0不应该 (SHOULD NOT) 在新的实现中使用. 然而, 为了与遗留系统兼容, 某些实现可能需要理解SSL 2.0格式的ClientHello.
E.2.1. SSL 2.0 ClientHello
SSL 2.0 ClientHello具有不同的格式:
uint16 msg_length; /* 最高位必须为1 */
uint8 msg_type; /* 必须为1 */
Version version; /* 客户端希望的版本 */
uint16 cipher_spec_length; /* 不能为0 */
uint16 session_id_length; /* 必须为0或16 */
uint16 challenge_length; /* 不能为0 */
CipherSpec cipher_specs[...];
SessionID session_id;
Challenge challenge;
E.2.2. 处理SSL 2.0 ClientHello
TLS 1.2服务器可以 (MAY) 接受以SSL 2.0格式封装的ClientHello, 但必须 (MUST):
- 检查msg_length的最高位
- 验证格式的有效性
- 将其转换为TLS格式进行处理
- 响应TLS格式的ServerHello
E.2.3. 安全考虑
重要: 支持SSL 2.0格式的ClientHello不意味着支持SSL 2.0协议本身. SSL 2.0有许多已知的安全漏洞, 禁止 (MUST NOT) 协商使用.
E.2.4. 实现建议
- TLS 1.2客户端禁止 (MUST NOT) 发送SSL 2.0格式的ClientHello
- TLS 1.2服务器对SSL 2.0格式ClientHello的支持现在是可以 (MAY), 而不是应该 (SHOULD)
- 发送SSL 2.0格式ClientHello是不应该 (SHOULD NOT) 的
- 未来的TLS版本可能会将此更改为不应该 (SHOULD NOT) 支持
E.3. Avoiding Man-in-the-Middle Version Rollback (避免中间人版本回退)
协议的早期版本容易受到版本回退攻击, 攻击者可能会强制连接使用早期 (较弱) 的协议版本.
E.3.1. 防护机制
TLS 1.2使用多种机制防止版本回退:
-
Finished消息验证:
- Finished消息包含所有握手消息的哈希
- 包括ClientHello和ServerHello中的版本字段
- 任何版本修改都会导致Finished验证失败
-
TLS_FALLBACK_SCSV:
- RFC 7507定义的Signaling Cipher Suite Value
- 客户端在重试连接时使用较低版本时包含此值
- 服务器如果支持更高版本则拒绝连接
E.3.2. 实现要求
客户端必须 (MUST):
- 记录之前尝试的版本
- 在降级重试时包含TLS_FALLBACK_SCSV
- 验证Finished消息
服务器必须 (MUST):
- 检查TLS_FALLBACK_SCSV
- 如果支持更高版本, 发送inappropriate_fallback警报
- 正确计算和验证Finished消息
E.3.3. 示例场景
正常连接:
客户端 -> ClientHello (TLS 1.2)
服务器 <- ServerHello (TLS 1.2)
... 正常握手 ...
成功!
合法降级:
客户端 -> ClientHello (TLS 1.2)
服务器 <- ServerHello (TLS 1.1)
... TLS 1.1握手 ...
成功!
检测到的攻击:
客户端 -> ClientHello (TLS 1.2)
攻击者修改为 (TLS 1.0)
服务器 <- ServerHello (TLS 1.0)
... 握手继续 ...
客户端 -> Finished (验证失败!)
连接中止!
使用SCSV的重试:
客户端 -> ClientHello (TLS 1.2) - 失败
客户端 -> ClientHello (TLS 1.1, TLS_FALLBACK_SCSV)
服务器检测到SCSV且支持TLS 1.2
服务器 <- Alert: inappropriate_fallback
连接中止 - 检测到降级攻击!
注意: 完整的兼容性信息和详细说明, 请参考RFC 5246附录E的完整文本.