我有一个HTTP服务器,运行HTTP和HTTPS,使用Javas NIO和SSL库编写。在HTTPS模式下,它可以使用或不使用客户端证书进行通信。但是,我想进行重新谈判。在这里,客户端将使用HTTPS连接,浏览资源,然后当它们访问高度安全的资源时,服务器会向客户端询问其证书。我一直遇到一些问题,需要知道工作流程应该是什么。以下是我在IE 9和Chrome中观察到的内容。
1)当客户端请求安全资源时,我完全响应HTTP请求。然后我在
完成后向客户挑战他们的证书engine.setNeedClientAuth(true);
engine.beginHandshake();
结果是来自客户端的TCP FIN(它关闭了它的连接端),并且重新协商失败。
2)当客户端请求安全资源时,我会在响应之前质询证书。在这种情况下,交换发生时,两个浏览器都会弹出对证书的请求,但是一旦弹出提示,就会从客户端发送TCP FIN并重新协商终止。然后,客户端发送另一个最终拥有证书的请求,有时我必须两次提出质疑。
所以我的问题是,应该发生什么?初始浏览器连接应该保持打开状态,还是像这样正常终止?
注意:另一个非常有趣的观察是,在方案2中,当浏览器关闭TCP连接时,它会在您选择证书后重新连接。但它不会重新发布请求,它只是坐在那里并期望服务器响应?在NIO术语中,它等待OP_READ,这意味着套接字输入缓冲区上没有数据。浏览器是否期望对原始消息的响应是否终止了连接?
奇怪的是,这个工作流程绝对没有文档或规范,但对于我测试过的所有浏览器,他们似乎都遵循这个工作流程。
答案 0 :(得分:1)
(1)是不安全的,因此无需进一步讨论。在您要求提供凭证之前,您已经泄露了这些信息。
(2)是这样做的正确方法。如果配置为允许重新协商,则客户端不应关闭连接。由于去年左右的SSL安全问题,暂时存在默认情况下不允许进行SSL重新协商的阶段。你可能碰到了这个。在这种情况下,您应首先发出HTTP重定向,然后关闭最终的连接以强制客户端使用新连接,新连接应该要求提供客户端证书。你如何安排代码取决于你。