我正在尝试调试一些 Java 11 测试代码,该代码使用 SSLServerSocket 作为服务器,并使用 SSLSocket 作为回复。基本代码的工作原理如下:
server.setNeedClientAuth(false);
need_Client_Auth = server.getNeedClientAuth();
assertFalse("Unexpected need client authority returned", need_Client_Auth);
server.setNeedClientAuth(true);
need_Client_Auth = server.getNeedClientAuth();
assertTrue("Unexpected need client authority returned", need_Client_Auth);
SSLClient sClient = new SSLClient(client, addr, SSLClient.START_HANDSHAKE);
sClient.start();
SSLSocket reply = (SSLSocket) (server.accept());
reply.startHandshake(); //this throws an SSLException
这里的想法是只使用 needClientAuth/wantClientAuth 并测试 startHandshake 的输出,而无需获得正确的客户端身份验证。
测试期望 SSLException 抛出“空 [服务器] 证书链”消息,但实际上是“空 [客户端] 证书链”。该测试来自完全运行的 Java 8 构建,据我所知,所创建的证书是正确的,并且与 Java 8 对应的证书相同。
我只是不确定从哪里开始调试以及什么可能导致预期输出发生如此小的变化。如有任何帮助,我们将不胜感激!
经过几天的研究和深入研究 OpenJDK 11,我意识到我期望“空服务器证书链”的测试用例是不正确的。
在 Java 11 中,TLS 或 SSL 协议支持 TLSv1.2 和 TLSv1.3。测试用例主要基于以下伪代码来决定预期消息是什么:
if(protocolUsed == "TLSv1.3")
expectedMessage = "Empty client certificate chain";
else
expectedMessage = "Empty server certificate chain";
但是在 Java 8(这是此测试的来源)中,SSL 和 TLS 仅支持 TLSv1.2。这意味着实际的握手是在 TLSv1.3 中完成的,但 if 块中使用的协议仍然显示为 SSL 或 TLS。因此 TLSv1.3 的工作已经完成,但 if 块从未正确更新以解释它。我通过调试输出验证了所有这些。
我使用 Spring Boot 应用程序作为 mTLS 客户端,并使用 Netscaler 作为发生 mTLS 卸载的 mTLS 服务器。为了轻松测试启动应用程序和 Netscaler 之间的 mTLS 通信,我在启动应用程序上设置了 REST 端点。当我从 CLI 卷曲 REST 端点时,我的启动应用程序被设计为使用 Netscaler 启动 mTLS 分支。
起初,curl CLI 调用在启动应用程序时失败,并出现“空客户端证书链”错误。在我意识到我的 Spring boot 应用程序现在已使用 mTLS 设置后,我解决了这个问题。因此,即使是对此启动应用程序的curl 请求也必须遵循mTLS 规则。意识到这一点后,我开始发送额外需要的参数:curl --cert 和 --key。
现在,对 Spring Boot 应用程序的 CLI 调用可以正常工作了。启动应用程序进一步成功对 Netscaler 进行 mTLS 调用。
curl CLI ---> 启动应用程序 <---mTLS---> Netscaler