[ 
https://issues.apache.org/jira/browse/CXF-5652?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14065338#comment-14065338
 ] 

Andrei Shakirin commented on CXF-5652:
--------------------------------------

Hi Vjacheslav,

I think I know now why pure JVM properties do not work in case of SSL client 
authentication.
The problem is that in case of client authentication client needs access to own 
private key in keystore to sign proof of possession. Later server check the 
signature using client public key and if signature is OK, client has proved 
that it owns appropriate private key.
To access private key in keystore client needs additional password (that can be 
different from keystore password). You applied this password in your code as 
well, but in your case keystore password and key password are equal:
{code}
Client client = ClientBuilder.newBuilder().keyStore(keyStore, 
trustpass).trustStore(ts).build();
{code}

It seems that java doesn't support providing private key password using JVM 
properties. At least all samples with client authentication I found initialize 
Connection using keyManagerFactory and SSLContext:
http://vafer.org/blog/20061010073725/ 
http://www.rap.ucar.edu/staff/paddy/cacerts/index.html 

Alternatively you can provide initialized SSLContext into ClientBuilder instead 
applying keystores:
{code}
...
                String keystorePwd = "keystorePassword";
                String keyPwd = "keyPassword";

                KeyStore keyStore = KeyStore.getInstance("JKS");
                keyStore.load(new FileInputStream("c:/1/jks/keystore.jks"), 
keystorePwd .toCharArray());
                KeyStore trustStore = KeyStore.getInstance("JKS");
                trustStore.load(new FileInputStream("c:/1/jks/keystore.jks"), 
keystorePwd .toCharArray());
                SSLContext context = initSecurityContext(keyStore, trustStore, 
keyPwd);
                
                Client client = 
ClientBuilder.newBuilder().sslContext(context).build();
...
        private static SSLContext initSecurityContext(KeyStore keyStore,
                        KeyStore trustStore, String pwd) throws 
NoSuchAlgorithmException,
                        NoSuchProviderException, KeyStoreException,
                        UnrecoverableKeyException, KeyManagementException {
                KeyManagerFactory kmf = 
KeyManagerFactory.getInstance(KeyManagerFactory
                                .getDefaultAlgorithm());
                kmf.init(keyStore, pwd.toCharArray());
                TrustManagerFactory tmf = TrustManagerFactory
                                
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                tmf.init(trustStore);

                SSLContext context = SSLContext.getInstance("TLS", "SunJSSE");
                context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), 
null);
                return context;
        }
{code}
This code works successfully with client authentication scenario.

Conclusion:
1. It is possible to use JVM properties to provide keystore with public 
certificate, but not to access private key (perhaps Sun/Oracle engineers don't 
open this option for security reasons). Therefore it will works on your client 
only for server authentication scenario. 
2. As alternative option you can provide per-initialized SSLContext object to 
ClientBuilder.

Regards,
Andrei.

> WebClient with SSL: javax.net.ssl.SSLHandshakeException handshake_failure
> -------------------------------------------------------------------------
>
>                 Key: CXF-5652
>                 URL: https://issues.apache.org/jira/browse/CXF-5652
>             Project: CXF
>          Issue Type: Improvement
>          Components: JAX-RS
>    Affects Versions: 3.0.0-milestone2
>            Reporter: Vjacheslav Borisov
>            Assignee: Andrei Shakirin
>            Priority: Minor
>
> I got error when using WebClient with SSL using client certificate:
> javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
> I found a way to fix this error
>             KeyStore keyStore = KeyStore.getInstance("JKS");
>             String trustpass = "chageit";
>             File truststore = new 
> File("/home/slavb/.java/deployment/security/trusted.clientcerts");
>             keyStore.load(new FileInputStream(truststore), 
> trustpass.toCharArray());
>             KeyStore ts = KeyStore.getInstance("JKS");
>             truststore = new File("/etc/ssl/certs/trusted.cacerts");
>             ts.load(new FileInputStream(truststore), "".toCharArray());
>             Client client = ClientBuilder.newBuilder().keyStore(keyStore, 
> trustpass).
>                     trustStore(ts).build();
> And I have question, why WebClient is not working like embedded in java 
> URLConnection or 
> apache http client when I specify system properties
> -Djavax.net.ssl.trustStore=/etc/ssl/certs/trusted.cacerts 
> -Djavax.net.ssl.keyStore=/home/slavb/.java/deployment/security/trusted.clientcerts
>  
> -Djavax.net.ssl.keyStorePassword=changeit
> (i got error javax.net.ssl.SSLHandshakeException: Received fatal alert: 
> handshake_failure when using SSL web client)
> Why it is need to configure ssl in code?



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to