JEP 244:TLS 应用层协议协商扩展
概述
扩展 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 握手,并检查协商后的值。