Java SSL socket -- 客户端证书证明

Java SSL socket -- client certificate proof

我正在尝试创建一个 java SSL 套接字服务器应用程序,几个 java SSL 套接字客户端应用程序将连接到该应用程序。为了保证通信双方的可信度,

(1) 如果客户端的证书是用服务器的私钥签名的,服务器应该只接受客户端连接

(2) 如果服务器的证书包含在客户端的受信任存储中,则客户端只应与服务器通信。

因为我是 JSSE 的新手,所以我只管理客户端应用程序连接到服务器,前提是它的证书包含在客户端的可信存储中(条件 2)。但是,我不知道如何实现我的第一个条件...

如果有任何帮助,我将不胜感激。

此致,Galveston01

如果我没有正确理解你的问题,你问的是如何启用双向SSL/TLS。这需要客户端验证服务器证书(问题中的第 2 点)和服务器验证客户端证书 - 称为客户端身份验证(第 1 点)。

听起来您有 "regular" 一种 TLS 工作方式。我假设您已经自己创建并签署了服务器证书(又名自签名证书),这就是为什么您必须将服务器证书本身导入客户端信任库 - 没有 CA root/intermediate 证书被用来签署它。

要启用客户端身份验证(第 1 点),您需要做两件事:

  1. 确保客户端证书在服务器的信任库中(和以前一样,如果这是不是自签名证书,那么您需要导入root/intermediate 将证书放入服务器信任库,无需导入证书本身)。由于您已经在客户端完成了此过程,因此应该不会有任何问题。

  2. 在服务器上配置 JSSE 以启用客户端身份验证。为此,您需要设置以下 属性:

    SSLServerSocket.setNeedClientAuth(真)

假设服务器上的信任库包含您的自签名客户端证书并且客户端上的信任库包含您的自签名服务器证书那么这应该有效。

如果您没有使用自签名证书,但实际上可以访问测试 CA 或使用真正签名的证书(没有理由不使用 letsencrypt),那么您可能需要查看以下问题的答案和评论这些问题:

client not sending certificate for client authentication in TLS

client auth failing for two way TLS

JSSE支持两个类KeyManagerFactoryTrustManagerFacory来支持服务器端和客户端认证。

客户端填写TrustManagerFactory的信息,服务器填写keyManagerFactory的信息。 服务器在连接客户端请求时填写如下参数:

final KeyManagerFactory kmf = KeyManagerFactory.getInstance(ksAlgorithm);
  kmf.init(ks, password.toCharArray());

连接的客户端代码:

final TrustManagerFactory tmf = TrustManagerFactory.getInstance(ksAlgorithm);
tmf.init((KeyStore) null);