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

标签 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,客户端身份验证仍然成功。为什么会这样?

最佳答案

我知道很久以前就有人问过这个问题,但还是 ;-)

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

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

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

关于java - TLS 服务器接受来自客户端的连接,即使服务器信任库中不存在客户端证书?为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/964547/

相关文章:

java - 如何从 guava cacheloader 获取缓存的值并更新该值而不更改缓存中的值?

xml - 为 TLS 向 XML 文档添加数字签名

css - 网站无法使用 HTTPS 正确加载

.net - 自签名证书。基础连接已关闭: Could not establish trust relationship

python - SSLError : unable to get local issuer certificate (_ssl. c:1076)

java - 为什么java 8注释@Contened使用128字节,这是大多数硬件上缓存行大小的两倍

java - 如何在 2 秒内不允许用户交互

java - 基于 boolean 变量 Autowiring Spring Bean

database - 从 GCP secret 管理器中读取 .DER 值并将其保存到 .DER 文件

swift - 快速和身份验证挑战中的 SSL Pinning