简体   繁体   English

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

[英]How do I sign a HTTP request with a X.509 certificate in Java?

How do I perform an HTTP request and sign it with a X.509 certificate using Java? 如何使用Java执行HTTP请求并使用X.509证书对其进行签名?

I usually program in C#. 我通常用C#编程。 Now, what I would like to do is something similar to the following, only in Java: 现在,我想要做的是类似于以下内容,仅在Java中:

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

In Java I have created a java.security.cert.X509Certificate instance but I cannot figure out how to associate it to a HTTP request. 在Java中,我创建了一个java.security.cert.X509Certificate实例,但我无法弄清楚如何将它与HTTP请求相关联。 I can create a HTTP request using a java.net.URL instance, but I don't seem to be able to associate my certificate with that instance (and I'm not sure whether using java.net.URL is even appropriate). 我可以使用java.net.URL实例创建HTTP请求,但我似乎无法将我的证书与该实例关联(我不确定使用java.net.URL是否合适)。

I'm not a C# programmer, but I'm presuming that code makes a call using HTTPS/TLS and provides a client certificate for authentication? 我不是C#程序员,但我假设代码使用HTTPS / TLS进行调用并提供客户端证书进行身份验证? Aka, you're not asking how to use WS-Security, right? Aka,你不是在问如何使用WS-Security,对吗?

In that case, I think the answers here and here will be of use to you. 在这种情况下,我认为这里这里的答案对你有用。 You need to use an openssl utility to import your certificate into a p12 client keystore. 您需要使用openssl实用程序将证书导入p12客户端密钥库。 If your server is using a non-standard CA or self-signed cert, you'll need to set up a client truststore with those certificates as well. 如果您的服务器使用的是非标准CA或自签名证书,则还需要使用这些证书设置客户端信任库。

At this point, look at the questions I've linked: you'll need to specify a whole slew of JVM arguments. 在这一点上,看看我链接的问题:你需要指定一大堆JVM参数。 Finally, try to make your call again (using standard Java objects or httpclient). 最后,尝试再次进行调用(使用标准Java对象或httpclient)。 The client should accept the server cert if your truststore is correct and the server should ask for a client cert. 如果您的信任库是正确的,并且服务器应该要求客户端证书,则客户端应该接受服务器证书。 If your keystore is set up correctly, the client with authenticate with the X.509 client cert and you'll be good to go. 如果您的密钥库设置正确,则客户端使用X.509客户端证书进行身份验证,您将很高兴。

I would recommend the open source HttpClient library from Apache Commons. 我会推荐Apache Commons的开源HttpClient库。 Covers this use case and many others. 涵盖此用例和许多其他用例。

It looks like you're trying to use HTTPS with client-certificate authentication. 看起来您正在尝试将HTTPS与客户端证书身份验证一起使用。 I'm assuming that your server is configured to request this (because the client certificate can only be requested by the server). 我假设您的服务器配置为请求此(因为客户端证书只能由服务器请求)。

In Java, java.security.cert.X509Certificate is really just the certificate (a public key certificate, without the private key). 在Java中, java.security.cert.X509Certificate实际上只是证书(公钥证书,没有私钥)。 What you need on the client side is to configure the private key with it. 客户端需要的是使用它配置私钥。 Assuming that your private key and certificate are in a keystore (to simplify, I'm assuming there's only one suitable certificate with its private key, perhaps with other certificates in the chain, in that keystore), and that you're using the default trust store: 假设您的私钥和证书位于密钥库中(为了简化,我假设只有一个合适的证书及其私钥,可能是链中的其他证书,在该密钥库中),并且您正在使用默认值信托商店:

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());

Other libraries will allow you to set the SSLContext or the KeyStore slightly differently, but the principles should be the same. 其他库将允许您稍微不同地设置SSLContextKeyStore ,但原则应该相同。

(You could also use the javax.net.ssl.keyStore system properties if it's appropriate.) (如果合适,您也可以使用javax.net.ssl.keyStore系统属性。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM