跳到主要内容

JEP 244:TLS 应用层协议协商扩展

QWen Max 中英对照

概述

扩展 javax.net.ssl 包以支持 TLS 应用层协议协商 (ALPN) 扩展,该扩展提供了为 TLS 连接协商应用层协议的手段。

动机

为了支持希望在相同的传输层端口上使用多个应用层协议的 TLS 客户端和服务器,ALPN 扩展允许客户端提供一份它所支持的应用层协议列表,并按照优先顺序排列。服务器随后可以选择其中一个客户端宣告的协议,并告知客户端在 TLS 连接中将使用哪个协议。

此 TLS 扩展的一个重要使用者将是 HTTP/2 客户端 (JEP 110),它将实现 HTTP/2

描述

此功能定义了一个公共 API,用于协商可通过给定 TLS 连接传输的应用层协议。协议名称在初始 TLS 握手期间在客户端和服务器之间传递。

TLS 应用程序可以使用扩展的 SSLParameters 类来获取和设置它在给定连接上可以支持的应用层协议列表。TLS 实现还使用此类来检索应用程序声明的协议名称。

默认行为是选择启用的应用协议值中服务器最倾向的交集值。

服务器应用程序还可以对外部扫描初始明文 ClientHellos,以选择适合此连接的 ALPN 协议值。该决策可能会基于提供的 TLS 协议、加密套件、服务器名称指示(Server Name Indication)值等做出。然后,服务器应用程序可以:

  • 如果支持的话,选择其中一个提供的协议,
  • 确定远程提供的和本地支持的 ALPN 值是否互斥,或者
  • 完全忽略该扩展。

服务器可能会根据连接期间可用的应用程序协议,更改其公布的连接参数,例如服务器证书。

在 SSL/TLS 握手开始后,SSLSocket/SSLEngine 上有了新的方法,允许应用程序查询是否已经选择了 ALPN 值(getHandshakeApplicationProtocol())。
一旦 TLS 握手完成,应用程序可以使用 getApplicationProtocol() 方法检查协商出了哪个协议。

所提出的设计遵循了与 JDK 8 中引入的 服务器名称指示扩展(JEP 114) 所使用的类似 API 方法,但不同之处在于 ALPN 值是与连接绑定的,而不是与 SSLSession 绑定。

测试

  • 客户端实现应能够与支持 HTTP/2 和 SPDY 的 Web 服务器协同工作(例如,Apache/mod_spdy、Jetty,以及可能的其他服务器)。SPDY 的重要性正在降低,因为 HTTP/2 是其公开的替代品。SPDY 的实现应该很快就会变得稀少。我们肯定会使用 JEP 110 中的新 HTTP/2 客户端进行测试。
  • 服务端实现应针对知名的、支持使用 ALPN 的 TLS 客户端实现进行测试(例如,GnuTLS、NSS、OpenSSL(测试版)和 Microsoft SChannel 8.1)。我们目前没有计划引入任何启用了 ALPN 的服务端应用程序。这里的大部分测试将是一些简单的 TLS 握手,并检查协商后的值。