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

时间:2009-06-08 11:56:53

标签: java ssl ssl-certificate

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);

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

2 个答案:

答案 0 :(得分:0)

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

两个可能的原因:您尚未设置信任管理器,因此将“搜索已安装的安全提供程序以获取相应工厂的最高优先级实现”(取自Javadoc)。也许你偶然安装了信任经理接受一切。

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

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

答案 1 :(得分:-1)

如果没有trustmananager,则需要客户端证书。

另一个姿势是客户端证书的一个发行者出现在服务器的信任库中。