跳到主要内容

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 协议、密码套件、服务器名称指示值等做出。然后,服务器应用程序可以:

  • 选择所提供的协议之一(如果它支持),
  • 确定远程提供的 ALPN 值和本地支持的 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(beta) 和 Microsoft SChannel 8.1)进行测试。我们目前不打算引入任何支持 ALPN 的服务器端应用程序。这里的大多数测试都是一些简单的 TLS 握手和检查协商值。