0

TLS 服务器接受来自客户端的连接,即使客户端证书不存在于服务器的信任库中。为什么?

服务器代码:

tlsContext = SSLContext.getInstance(SSL_PROTOCOL);
tlsContext.init(getMyKeyManagers(),null,null);
SSLServerSocketFactory fact = tlsContext.getServerSocketFactory();
tlsServerSock = (SSLServerSocket)fact.createServerSocket();
tlsServerSock.setNeedClientAuth(true);
tlsServerSock.setWantClientAuth(true);
tlsServerSock.bind(objSocketAddress);

并开始监听服务器套接字代码

客户代码:

SSLContext tlsContext = SSLContext.getInstance(SSL_PROTOCOL);
tlsContext.init(getMyKeyManagers(), getMyTrustManagers(), null);
SSLSocketFactory fact = tlsContext.getSocketFactory();
socket = fact.createSocket();
socket.connect(objSocketAddress);

如代码所示,在服务器端没有添加任何 TrustManager,客户端身份验证仍然成功。为什么会这样?

4

2 回答 2

0

我知道这个问题是很久以前提出的,但仍然;-)

两个可能的原因:您没有设置信任管理器,因此“将搜索已安装的安全提供程序以查找相应工厂的最高优先级实现”(取自Javadoc)。也许您不小心安装了信任管理器,接受了所有内容。

或者,您的客户端可能根本不尝试执行 TLS 客户端身份验证,因为您通过设置setWantClientAuthtrue. setNeedClientAuth这很可能会覆盖您在上面的行中所做的设置true。前者让服务器告诉客户端“如果你有证书给我,请发送它”,而后者说“如果你没有证书,甚至不要尝试......”。如果由于某种原因配置的密钥管理器没有为 TLS 客户端身份验证提供证书和私钥,则 TLS 握手将成功。

使用 TCP 嗅探器(例如 Wireshark)应该有助于查看 TLS 客户端身份验证是否实际发生。或者,您可以设置系统属性-Djavax.net.debug=all并通读 STDOUT 上的大量调试输出(请参阅调试 SSL/TLS 连接以了解更多信息)

于 2018-01-08T21:52:08.060 回答
-1

如果没有信任管理器,则不需要客户端证书。

另一个问题是客户端证书的颁发者之一存在于服务器的信任库中。

于 2009-06-08T12:03:09.973 回答