English 中文(简体)
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?

I usually program in C#. Now, what I would like to do is something similar to the following, only in 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. 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).

问题回答

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? Aka, you re not asking how to use WS-Security, right?

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. 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.

At this point, look at the questions I ve linked: you ll need to specify a whole slew of JVM arguments. Finally, try to make your call again (using standard Java objects or 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.

It looks like you re trying to use HTTPS with client-certificate authentication. 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). 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.

(You could also use the javax.net.ssl.keyStore system properties if it s appropriate.)

I would recommend the open source HttpClient library from Apache Commons. Covers this use case and many others.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签