How to sign an HTTP request with an X.509 certificate in Java?

How to execute an HTTP request and sign it using an X.509 certificate using Java?

I usually program in C #. Now I would like to do 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 created an instance of java.security.cert.X509Certificate , but I cannot figure out how to associate it with an HTTP request. I can create an HTTP request using an instance of java.net.URL, but it seems I can not associate my certificate with this instance (and I'm not sure if using java.net.URL is even suitable).

+6
java x509certificate client-certificates
source share
3 answers

I'm not a C # programmer, but I assume that this code makes a call using HTTPS / TLS and provides a client certificate for authentication? Aka, you are not asking how to use WS-Security, right?

In this case, I think the answers here and here will be useful to you. You need to use the openssl utility to import the certificate into the p12 client key store. If your server uses a non-standard CA or a self-signed certificate, you also need to configure a client network with these certificates.

At this point, consider the issues that I have related: you need to specify a whole host of JVM arguments. Finally, try making your call again (using standard Java objects or httpclient). The client must accept the server certificate if your trust server is correct, and the server must request the client certificate. If your keystore is configured correctly, the client authenticates with the X.509 client certificate and you will be well off.

+2
source

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

+1
source

It looks like you are trying to use HTTPS with client certificate authentication. I assume that your server is configured to request this (since the client certificate can only be requested by the server).

In Java, java.security.cert.X509Certificate is really just a certificate (public key certificate without private key). What you need on the client side is to configure a private key with it. Assuming that your private key and certificate are in the keystore (to simplify, I assume there is only one suitable certificate with its private key, possibly with other certificates in the chain, in this keystore) and that you use 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 up SSLContext or KeyStore slightly different way, but the principles should be the same.

(You can also use the system properties of javax.net.ssl.keyStore , if necessary.)

+1
source

All Articles