如何为新连接找到协商密码套件



为了进一步提高基于Jetty 9.3/JRE8 build 45的嵌入式web服务器应用程序的安全性,我想将我的服务器限制为仅服务TLS 1.2(或未来的1.2和1.3),并且只有这些密码套件:

0xC0,0x2B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 Y [RFC5289]

0xc,0x2C TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 Y [RFC5289]

然而,为了允许已经协商好的备用密码套件的用户代理在服务器的handle()函数中结束,Jetty将线程交给我,我需要允许一些其他密码套件通过,否则我无法发回一个简单的HTML页面,要求用户获得合适的浏览器。

所有这些都已与sslContextFactory对象正确设置,并且当我使用支持TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256和TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384的密码套件测试概念时工作正常。

我不知道为什么我的两个首选还没有工作。必须是一个ECDSA问题,因为我的谷歌Chrome浏览器有TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256作为首选套件也根据这个网站:cc.dcsec.uni-hannover.de

然而,一旦在我的handle()方法中,我需要能够找出上述密码套装中的一个是否被选中,以便在没有的情况下,我可以通知用户他需要一个支持TLS 1.2和椭圆曲线的浏览器,如FireFox或与EC启用的操作系统相结合,如需要Chrome(例如Windows作为Vista)等。

我检查了HTTP/1.1 RFC,并希望"连接"或"升级"HTTP标签会保留一些有用的东西。我还搜索了其他可以包含协商密码套件的HTTP头名称。

然后我研究了一些相关的HTTP over TLS的RFC,希望也许有一种方法可以要求一些头重写以包含带有密码套件的标记。我还查看了servlet请求对象上是否有一些方法可以披露密码套件,但最接近的是更通用的isSecure()或getScheme() (http/https)。我还列举了所有的头名称和相关的值,看看是否有什么。

最后,我找到了一个来自微软的链接,解释如何从TLS记录中提取信息,但后来我意识到,当我的handle()方法被Jetty调用时,信息不再可用。

我知道TCP/IP和TLS 1.2是在Jetty获得连接之前处理的。因此,密码套件可能不可用,就像TCP/IP接受不能在handle()方法中早期阻止(没有连接/断开连接)一样。

但也许有人知道一种方法来获得密码套件,或者可以结束我的搜索,说这是不可能的。

这里的一般理念是,我将只服务HTTPS TLS 1.2/HTTP 2.0与上述密码套件和HSTS +重定向所有HTTP到HTTPS,但我总是需要允许其他不需要的连接来到我的handle()方法发送回一个基本的HTML页面请求浏览器升级。因此,在我的handle()中,我需要找出我在每个连接基础上处理的连接。密码套件是我最不需要的安宁。

所以或者可以有一种方法来设置一个消息,将发送回用户代理(HTML),如果我只接受以上两个密码套件与sslContextFactory的setincleciphersuits()关闭门。然后,用户将看到该消息,而不是浏览器显示的默认错误,该错误是由于缺乏通用密码套件支持而导致密码套件协商失败。

许多谢谢。

假设您正在使用具有启用SecureRequestCustomizerServerConnectorHttpConfiguration,那么您可以这样做…

String cipherSuite = request.getAttribute("javax.servlet.request.cipher_suite");

这将返回SSLSession在已建立的安全连接上使用的密码套件的名称。

最新更新