如何使用Java中的X.509证书签署HTTP请求?

时间:2010-05-26 19:24:01

标签: java http https x509certificate client-certificates

如何使用Java执行HTTP请求并使用X.509证书对其进行签名?

我通常用C#编程。现在,我想要做的是类似于以下内容,仅在Java中:

 private HttpWebRequest CreateRequest(Uri uri, X509Certificate2 cert) 
 {
     HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
     request.ClientCertificates.Add(cert);
     /* ... */
     return request;
 }

在Java中,我创建了一个java.security.cert.X509Certificate实例,但我无法弄清楚如何将它与HTTP请求相关联。我可以使用java.net.URL实例创建HTTP请求,但我似乎无法将我的证书与该实例关联(我不确定使用java.net.URL是否合适)。

3 个答案:

答案 0 :(得分:2)

我不是C#程序员,但我假设代码使用HTTPS / TLS进行调用并提供客户端证书进行身份验证? Aka,你不是在问如何使用WS-Security,对吗?

在这种情况下,我认为答案herehere对您有用。您需要使用openssl实用程序将证书导入p12客户端密钥库。如果您的服务器使用的是非标准CA或自签名证书,则还需要使用这些证书设置客户端信任库。

此时,请查看我链接的问题:您需要指定一大堆JVM参数。最后,尝试再次进行调用(使用标准Java对象或httpclient)。如果您的信任库是正确的,并且服务器应该要求客户端证书,则客户端应该接受服务器证书。如果您的密钥库设置正确,则客户端使用X.509客户端证书进行身份验证,您将会很高兴。

答案 1 :(得分:1)

我会推荐Apache Commons的开源HttpClient库。涵盖了这个用例和许多其他用例。

答案 2 :(得分:1)

看起来您正在尝试将HTTPS与客户端证书身份验证一起使用。我假设您的服务器配置为请求此服务(因为客户端证书只能由服务器请求)。

在Java中,java.security.cert.X509Certificate实际上只是证书(公钥证书,没有私钥)。客户端需要的是使用它配置私钥。 假设您的私钥和证书位于密钥库中(为了简化,我假设只有一个合适的证书及其私钥,可能是链中的其他证书,在该密钥库中),并且您正在使用默认值信托商店:

KeyStore ks = ...
/* load the keystore */

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);

URL url = new URL("https://example/");
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();

connection.setSSLSocketFactory(sslContext.getSSLSocketFactory());

其他库允许您稍微区别地设置SSLContextKeyStore,但原则应该相同。

(如果合适,您还可以使用javax.net.ssl.keyStore系统属性。)