使用Java客户端连接带有Openssl和客户端认证的服务器

3

我需要编写一个Java客户端来连接到一个SSL服务器。该服务器使用openssl证书,并配置为进行客户端身份验证。

我似乎找不到任何有用的在线资源,可以帮助我(我对openssl和SSL知之甚少)理解如何实现我的客户端。

求助!

3个回答

4

这里的关键是您正在使用客户端身份验证,因此您需要私钥和证书来标识自己。您可以通过在初始化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.keyStorejavax.net.ssl.keyStorePassword。分别应为用户密钥库的路径和密钥库的“密钥条目”的密码。

当使用这些属性时,您可以创建一个新的支持客户端身份验证的SSLSocket,如下所示:

SocketFactory factory = SSLSocketFactory.getDefault();
Socket socket = factory.createSocket(host, port);

由于您正在使用“默认”SSLSocketFactory,它依赖于系统范围的属性,因此在JVM中创建的所有套接字都将使用相同的证书进行身份验证。如果您需要更多控制权,则必须使用上面的“可定制设置”。


我目前正在尝试让您的代码运行,但有一些问题:1. KeyStore.getDefaultAlgorithm() 似乎不存在。2. 是否有某种(任何)方法可以零配置地获取/生成密钥库?目前,我被调用 load 中的“…”所困扰。 - Zarkonnen
抱歉,“KeyStore”那里有错误;我已经修复了。至于初始化密钥库,是的,有一种方法使用系统属性,并为重要属性设置默认值。我会在我的答案中更新这个信息。 - erickson
如果您需要帮助实际创建密钥对、获取证书并将它们全部放入KeyStore中,请提出请求。 - erickson

1

Java在标准API中包含SSL支持。请查看1.5.0 javadoc中的这些类:

如果您自己处理通信逻辑,请使用SSLSocket

如果服务器端使用HTTP协议,请使用HttpsURLConnection


0
你可以使用httpclient。看一下这个SSL指南

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接