如何使用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是否合适)。
答案 0 :(得分:2)
我不是C#程序员,但我假设代码使用HTTPS / TLS进行调用并提供客户端证书进行身份验证? Aka,你不是在问如何使用WS-Security,对吗?
在这种情况下,我认为答案here和here对您有用。您需要使用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());
其他库允许您稍微区别地设置SSLContext
或KeyStore
,但原则应该相同。
(如果合适,您还可以使用javax.net.ssl.keyStore
系统属性。)