JAVA - SSL - Client Certifcates

11,036

You can either create a specific SSLContext (using a KeyManager initialised with the keystore containing your client cert + private key), from which you derive an SSLSocketFactory, which you set into your HttpsURLConnection, or use the global settings.

You could set the following system properties (for the global settings):

  • javax.net.ssl.keyStore=path/to/keystore.pfx
  • javax.net.ssl.keyStoreType=PKCS12
  • javax.net.ssl.keyStorePassword=xxxxxxxxx

Alternatively, you can create your own KeyManagerFactory/KeyManager as described in this answer.

Since you've imported the server certificate in your cacerts, use null for the TrustManager[] argument of SSLContext.init() (it will pick up the default values).

In addition, since you're on OSX, you could use the KeychainStore directly. To do so, use ....keyStore=NONE, keyStoreType=KeychainStore and keyStorePassword=- (any password will do, since access to the key will be granted when you need it from the OS). I'm not sure if it works on Lion, though. Note that it may fail if you have more than one cert+private key in your store (see this issue).

Share:
11,036
user1161538
Author by

user1161538

Updated on June 04, 2022

Comments

  • user1161538
    user1161538 almost 2 years

    I've been developing a WS client using JAVA and I'm having a problem with SSL authentication. The WS are created on WCF and I have no access to the server, they work through HTTPS and uses a client certificate that needs to be installed on the client first. The server guys sent me a PFX certificate which I successfully installed on the OS (I'm using OS X) and I could then access the WS via a browser (Safari or FF are both that I tried which previously couldn't access the WSs). I thought any app in the OS would use this certs but when I'm tried my JAVA app it didn't work; at first the following error was being thrown:

    "javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"

    I solved this by exporting the certificate to a CER file and using the keytool command line tool to add the certificate into the "cacerts" keyStore JAVA uses. But after this error went away the following started appearing: "403, forbidden". This is obviously because it's not using the SSL client cert for the site but I haven't been able to find a way to send it to it. Any help would be appreciated.

    The following is the code I use to post to the WS:

    URL url = new URL(p_url);
    
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setDoOutput(true);
    
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", contentType);
    
    OutputStream out = conn.getOutputStream(); // on this line it shows the error
    
  • kosa
    kosa over 12 years
    It seems OP already did it. Read second paragraph in his question.
  • Bruno
    Bruno over 12 years
    If you're confused between keystore/truststore, you may want to read this: stackoverflow.com/a/6341566/372643
  • user1161538
    user1161538 over 12 years
    Thank you, I had actually tried tho but I was missing the keyStoreType=PKCS12.