users@jersey.java.net

[Jersey] Re: Client Authentication with Certificate

From: Alperovitch, Yasmine <Yasmine.Alperovitch_at_emc.com>
Date: Mon, 9 Feb 2015 15:32:27 +0000

AFAIK, there's no way to specify which certificate you want java to use in the SSL handshake, if you use the default KeyManagers.
It'll just use the first certificate it has in the keystore that matches the current session.
So if you have 2 certificates that are using RSA keys there's no real way for you to know which certificate will get chosen.
What you can do, is implement you own X509ExtendedKeyManager that will choose the right keystore entry to use, and feed that to your SSLContext. I've seen something similar being done in Jetty's code:
http://grepcode.com/file/repo1.maven.org/maven2/org.eclipse.jetty.aggregate/jetty-all/9.2.6.v20141205/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java#AliasedX509ExtendedKeyManager


Thanks,
Jasmine

-----Original Message-----
From: John MacAuley [mailto:john_at_blackacorn.ca]
Sent: Monday, February 09, 2015 9:59 AM
To: users_at_jersey.java.net
Subject: [Jersey] Re: Client Authentication with Certificate

Tom,

I have not seen a reply so I will offer up one possible solution.

If you are using the standard HTTP client provider in Jersey (HttpURLConnection) you can specify the keystore and truststore on as parameters into the VM. In my experience the HttpURLConnection provider will respect these parameters and you do not need any special SSL code. I prefer this over writing code to load and configure the stores. Here are the parameters:

        -Djavax.net.ssl.keyStore=$KEYSTORE \
        -Djavax.net.ssl.keyStorePassword=$PASSWORD \
        -Djavax.net.ssl.trustStore=$TRUSTSTORE \
        -Djavax.net.ssl.trustStorePassword=$PASSWORD \

In your keystore place your client's private key and any CA certificates associated with your key. Your client will pick up the first private key in the keystore. Since there is only one you are good to go. In the truststore place the certificate of the server you would like to trust.

Also, you can use the following to track the progress of SSL setup:

        -Djavax.net.debug=all \

Let me know if that works for you. It has worked fine for me.

John

On 2015-02-08, at 9:37 AM, TomJones <bagelbig_at_yahoo.com> wrote:

> I am attempting to access a secured server (https://localhost:55555/rest).
> I have the server side certificate in my Windows certificate store.
> I have the client side certificate with which I wish to authenticate
> also in my Windows certificate store.
> (Note, I need to not only accept the server side, but authenticate
> with my own certificate).
>
> Attempting to connec to the service with a browser (IE or Chrome)
> causes a prompt to select the client certificate to pop up (good) and
> then notice about the server side certificate (good). Now I am
> attempting to access the service via java rather than just a browser.
>
> I have done the following:
>
> HostnameVerifier hostnameVerifier = getHostnameVerifier();
>
> KeyStore ks = KeyStore.getInstance("Windows-MY");
> ks.load(null, null);
> SslConfigurator sslConfigDirect = SslConfigurator.newInstance()
> .keyStore(ks)
> .trustStore(ks);
>
> SSLContext sslContext = sslConfigDirect.createSSLContext();
>
> Client client = ClientBuilder.newBuilder()
> .sslContext(sslContext)
> .hostnameVerifier(hostnameVerifier)
> .build();
>
> HttpAuthenticationFeature authFeature =
> HttpAuthenticationFeature.basicBuilder().credentials("name","password"
> ).build();
> client.register(authFeature);
>
> WebTarget webTarget =
> client.target("https://localhost:55555/rest").path("list");
> Response response = webTarget.request().get();
>
>
>
>
> private HostnameVerifier getHostnameVerifier() {
> HostnameVerifier hostnameVerifier = new HostnameVerifier() {
> @Override
> public boolean verify(String s, SSLSession sslSession) {
> return true;
> }
> };
>
> return hostnameVerifier;
> }
>
>
>
> So my questions are:
> 1) What am I doing wrong?
> 2) How do I specify which certificate from the certificate store I
> wish to use (I have multiple at that location which I can enumerate by
> doing a
> KeyStore.Aliases() and getting a correct list.
> 3) For specifying credentials, which name/password does it want
> (friendly, alias, primary, CN, etc.?)
>
> Thank you.
>
>
>
> --
> View this message in context:
> http://jersey.576304.n2.nabble.com/Client-Authentication-with-Certific
> ate-tp7583106.html Sent from the Jersey mailing list archive at
> Nabble.com.