我必须编写一个 Java 客户端来连接到 SSL 服务器。服务器使用 openssl 证书,并配置为进行客户端身份验证。
我似乎无法在网上找到任何有用的资源来帮助我(谁对 openssl 和 SSL 一无所知)了解谁来实现我的客户端。
帮助!
这里的转折是您正在使用客户端身份验证,因此您需要一个私钥和一个证书来识别您自己。您通过在初始化 SSLContext 时指定 KeyManagers 将其提供给 JSSE。
以下是基本步骤。JSSE API 在 Java 6 中得到了显着改进,但我会坚持使用 Java 5,以防你被困在那个版本上。
KeyStore tks = KeyStore.getInstance(KeyStore.getDefaultType());
tks.load(...); /* Load the trust key store with root CAs. */
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(tks);
KeyStore iks = KeyStore.getInstance(KeyStore.getDefaultType());
iks.load(...); /* Load the identity key store with your key/cert. */
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(iks, password);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SocketFactory factory = ctx.getSocketFactory();
Socket socket = factory.createSocket(host, port);
使用提供程序时,可以使用另一种“零配置”方案SunJSSE
。我相信许多其他供应商(如 IBM)都遵循了相同的模式,并且也会发挥作用。该机制使用系统属性,JSSE 参考指南中有详细描述。
对于客户端身份验证,重要的属性是javax.net.ssl.keyStore
和javax.net.ssl.keyStorePassword
。这些值应该分别是用户密钥存储的路径和该密钥存储的“密钥条目”的密码。
使用这些属性时,您可以创建一个支持客户端身份验证的新 SSLSocket,如下所示:
SocketFactory factory = SSLSocketFactory.getDefault();
Socket socket = factory.createSocket(host, port);
由于您使用的是 "default" SSLSocketFactory
,这取决于系统范围的属性,因此在 JVM 中创建的所有套接字都将使用相同的证书进行身份验证。如果您需要更多控制,则必须使用上面的“可自定义设置”。
Java 在标准 API 中包含 SSL 支持。查看 1.5.0 javadoc 中的这些类:
SSLSocket如果你自己做通讯逻辑。
HttpsURLConnection如果服务器端使用 HTTP
你可以使用httpclient。看看这个SSL 指南。