即使服务器信任库中不存在客户端证书,TLS 服务器也会接受来自客户端的连接? 为什么?
即使服务器的信任库中不存在客户端证书,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,但客户端身份验证仍然成功。 为什么会这样呢?
TLS server accepts connection from the client even client cetificate is not present in server's truststore. Why?
Server Code:
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);
and start listening on Server socket code
Client Code:
SSLContext tlsContext = SSLContext.getInstance(SSL_PROTOCOL);
tlsContext.init(getMyKeyManagers(), getMyTrustManagers(), null);
SSLSocketFactory fact = tlsContext.getSocketFactory();
socket = fact.createSocket();
socket.connect(objSocketAddress);
As code depicts there are no TrustManagers added at server side still client authentication is successful. why is so?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我知道这个问题很久以前就被问过,但仍然;-)
两个可能的原因:您没有设置信任管理器,因此“将搜索已安装的安全提供程序以查找适当工厂的最高优先级实现”(取自Javadoc)。 也许您意外地安装了信任管理器并接受了所有内容。
或者,您的客户端可能根本不会尝试进行 TLS 客户端身份验证,因为您通过将
setWantClientAuth
设置为true
将要求配置为可选。 这很可能会将您在setNeedClientAuth
上方所做的设置覆盖为true
。 前者让服务器告诉客户端“如果你有我的证书,请发送它”,而后者则说“如果你没有证书,甚至不要尝试......”。 如果由于某种原因配置的密钥管理器未提供用于 TLS 客户端身份验证的证书和私钥,则 TLS 握手将成功。使用 TCP 嗅探器(例如 Wireshark)应该有助于查看 TLS 客户端身份验证是否确实发生。 或者,您可以设置系统属性
-Djavax.net.debug=all
并读取 STDOUT 上的大量调试输出(请参阅 调试 SSL/TLS 连接 以了解更多信息)I know this question was asked quite a while ago, but still ;-)
Two possible reasons: You haven't set a trust manager so the "installed security providers will be searched for the highest priority implementation of the appropriate factory" (taken from the Javadoc). Maybe you installed a trust manager by accident accepting everything.
Alternatively your client might not attempting to do TLS client-authentication at all because you configured the requirement to be optional by setting
setWantClientAuth
totrue
. This most likely overwrote the setting you've done the line abovesetNeedClientAuth
totrue
. The former lets the server tell the client "if you've got a certificate for me, please send it" while the latter says "if you don't have a certificate, don't even try...". If for some reason the configured key manager doesn't provide a certificate and private key for TLS client authentication the TLS handshake will succeed.Using a TCP sniffer (e.g. Wireshark) should help to see if TLS client authentication is actually taking place. Alternatively you can set the system property
-Djavax.net.debug=all
and read through a whole lot of debug output on STDOUT (see Debugging SSL/TLS Connections to learn more about that)如果没有信任管理器,则不需要客户端证书。
另一个潜在问题是客户端证书的颁发者之一存在于服务器的信任库中。
if there is no trustmananager, then a client cert is nog needed.
an other posebillity is that one of the issuers of the client certificate is present in the truststore at the server.