我有一些连接到远程服务器的Java NIO库的代码。我编写了异步回调连接的代码,并且当主机只是常规TCP服务器时,它可以很好地工作。但是当服务器使用SSL时,似乎我必须进行大量修改。我想做的是设置SSL,仅在检查服务器证书是否有效(即由证书颁发机构颁发且未过期)的点上。我不想做比这更广泛的事情(如名称检查)。换句话说,我只想要非常基本的SSL行为。而且,我计划在Android上运行此应用程序,因此客户端方面真的不能进行太多与外部密钥库等相关的操作。我希望在应用程序内部完成所有必需的操作。如果我能避免任何外部证书文件就好了。
我不确定接下来应该做什么。我在这里找到了一些NIO套接字设置代码,如下所示:
在此之后,还有一堆表面上可怕的SSL握手代码必须手动实现。以上代码的问题是我不知道在client.jks文件中应该放什么。我不想一开始就必须要有某种类型的密钥库文件。
我找到了一个名为Naga的库,声称实现了SSL套接字,但它在我设置的SSL套接字服务器上无法工作 - 我得到了一个异常: sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径。
有任何建议吗?
我不确定接下来应该做什么。我在这里找到了一些NIO套接字设置代码,如下所示:
private void setupSecurity() {
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextInt();
KeyStore clientKeyStore = KeyStore.getInstance("JKS");
clientKeyStore.load(new FileInputStream("client.jks"), "KeyStorePassword".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(clientKeyStore);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(clientKeyStore, "KeyInKeystorePassword".toCharArray());
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), secureRandom);
}
在此之后,还有一堆表面上可怕的SSL握手代码必须手动实现。以上代码的问题是我不知道在client.jks文件中应该放什么。我不想一开始就必须要有某种类型的密钥库文件。
我找到了一个名为Naga的库,声称实现了SSL套接字,但它在我设置的SSL套接字服务器上无法工作 - 我得到了一个异常: sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径。
有任何建议吗?
SSLContext
,与使用NIO/BIO无关,您甚至可能不需要执行此操作。另外,使用clientKeyStore
作为信任管理器并不一定合理。最好使用TrustManager.getDefaultAlgorithm()
代替 TMF 中的 "SunX509"(因为默认值是 PKIX,而不是 SunX509)。 - Bruno