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

时间:2015-07-11 15:52:27

标签: security jetty embedded-jetty

为了进一步提高基于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]

0xC0,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问题,因为根据此网站,我的Goolge Chrome也将TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256作为首选套件:cc.dcsec.uni-hannover.de

然而,一旦在我的handle()方法中,我需要能够找出上面的密码套装之一是否被选举,所以在NOT的情况下我可以通知用户他需要一个支持TLS的浏览器1.2和Elliptic Curve本身就像FireFox一样,或者与支持EC的操作系统结合使用,需要Chrome(例如Windows的Vista)等。

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

然后我研究了一些关于HTTP over TLS的相关RFC,希望可能有一种方法可以让一些头重写包含一个带有密码套件的标签。我还看看servlet请求对象上是否有一些方法可以公开密码套件,但最接近的是更通用的isSecure()或getScheme()(http / https)。我还列举了所有标题名称和相关值,以查看是否存在某些内容。

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

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

但也许有人知道如何获得密码套件或者可以通过说不可能来结束我的搜索。

这里的一般原则是我只使用上面的密码套件来管理HTTPS TLS 1.2 / HTTP 2.0,并且HSTS +将所有HTTP重定向到HTTPS但是我总是需要允许其他UNWANTED连接来到我的handle()方法发回基本HTML页面以请求升级浏览器。因此,在我的句柄()中,我需要找出每个连接基础上的连接处理内容。密码套件是我需要的最后一个和平。

因此,如果我通过仅接受带有sslContextFactory的setIncludeCipherSuits()的上述密码套件来关闭门,那么可以有一种方法来设置将被发送回用户代理(HTML)的消息。然后,用户将看到该消息而不是浏览器根据缺少通用密码套件支持的失败密码套件协商显示的默认错误。

非常感谢。

1 个答案:

答案 0 :(得分:0)

假设您使用ServerConnectorHttpConfiguration启用了SecureRequestCustomizer,那么您可以执行此操作...

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

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