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,客户端身份验证仍然成功。为什么会这样?
答案 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,则需要客户端证书。
另一个姿势是客户端证书的一个发行者出现在服务器的信任库中。