我需要编写一个Java客户端来连接到一个SSL服务器。该服务器使用openssl证书,并配置为进行客户端身份验证。
我似乎找不到任何有用的在线资源,可以帮助我(我对openssl和SSL知之甚少)理解如何实现我的客户端。
求助!
这里的关键是您正在使用客户端身份验证,因此您需要私钥和证书来标识自己。您可以通过在初始化SSLContext时指定KeyManagers来向JSSE提供此信息。
以下是基本步骤。虽然Java 6中的JSSE API得到了显着改进,但如果您仍在使用该版本,则我将坚持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);
由于您正在使用“默认”SSLSocketFactory
,它依赖于系统范围的属性,因此在JVM中创建的所有套接字都将使用相同的证书进行身份验证。如果您需要更多控制权,则必须使用上面的“可定制设置”。
Java在标准API中包含SSL支持。请查看1.5.0 javadoc中的这些类:
如果您自己处理通信逻辑,请使用SSLSocket。
如果服务器端使用HTTP协议,请使用HttpsURLConnection。