我有一个简单的服务器程序,它从开放无线网络上的众多硬件设备收集数据。我想确保连接到我的端口的任何人都不能发送命令或监听我的流量,所以我需要服务器来验证客户端。我找到了一些示例,但大多数示例似乎都采用了从客户端验证服务器的方法。我是 SSL 和套接字编程的新手。
来 self 的客户
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream("KeyStore"), "password".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keystore);
SSLContext context = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
context.init(null, trustManagers, null);
SSLSocketFactory sf = context.getSocketFactory();
return (SSLSocket) sf.createSocket(host, port);
在我的服务器上
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(newFileInputStream("server"),"password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "password".toCharArray());
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
server = (SSLServerSocket) ssf.createServerSocket(this.port);
我不是很清楚每件事都在做什么,但从这个例子中我发现它是双向身份验证,所以有点矫枉过正。我想我只需要其中一段代码,但对 SSL 的了解还不够深,无法知道是哪一段。哪一方需要 keystore ?谁需要 key 和证书?谢谢
最佳答案
如果您只想将客户端身份验证添加到现有服务器身份验证中,请在服务器代码末尾添加此行:
server.setNeedClientAuth(true);
如果只希望服务器授权客户端,反之亦然,在服务器调用server.setUseClientMode(true)
,在服务器端调用setUseClientMode(false)
您在返回之前在客户端上创建的 SSLSocket。请注意,此选项意味着客户端设备可能正在连接到其他人的服务器,并且无法知道这一点。
在任何一种情况下,服务器都需要一个信任库——它可以与它的 keystore 相同——以及客户端正在安装的证书副本。客户端将需要提供此证书的 key 对。
关于Java SSL 套接字客户端身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14168430/