WebService call and SSL / certificate issue

To begin with, I have little knowledge about setting up a keystore, etc. in java

I am trying to call a SOAP web service, I got wsdl, generated code, etc. Everything seems fine until I deployed it and tried to call the WS call.

Here is my setup:

  • Tomcat 7.0.35
  • Java, jdk 1.6.0_39
  • Pfx file and password
  • the project is deployed as a standard web application (war) for tomcat

When I run the code, I got the following exception:

Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://tallyservices-qa.olson.com/tallyDemo2WebServices/tallyDemo2/sms: Received fatal alert: certificate_unknown at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1336) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1320) at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:622) at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) ... 27 more Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1837) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1019) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1203) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1230) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1214) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230) at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:170) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1280) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1231) at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:183) at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47) at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1293) ... 30 more 

I made the following suggestion: How to convert a .pfx file to a private key keystore? to install the certificate on my keystore:

 keytool -importkeystore -srckeystore C:\somefolder\mypfxfile.pxf -srcstoretype pkcs12 -destkeystore C:\somefolder\clientcert.jks -deststoretype JKS 

and I got:

 Enter destination keystore password: <mypassword> Re-enter new password: <mypassword> Enter source keystore password: <pxf_password> Entry for alias 67eb31f6 successfully imported. Import command completed: 1 entries successfully imported, 0 entries failed or cancelled 

So, everything looks good so far, I bounced off my cat and clicked on Servlet again, and I still get the same error.

What else am I missing here? Should I tell tomcat about the certificate or something else?

Thanks in advance for the help and apologies for my noobility in the keystore and certificate area.

EDIT: So I thought about Carlo Pellegrini's help, that I need to add storage to tomcat: so now my tomcat starts with the optional JAVA_OPTS parameter:

 "-Djavax.net.ssl.trustStore=C:\somefolder\clientcert.jks -Djavax.net.ssl.trustStorePassword=somepassword" 

and now i got:

 Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty 

Hence: Error - the trustAnchors parameter must be non-empty and received java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty when using cas - does it look like my power of attorney was not found?

I understood my previous command:

 keytool -importkeystore -srckeystore C:\somefolder\mypfxfile.pxf -srcstoretype pkcs12 -destkeystore C:\somefolder\clientcert.jks -deststoretype JKS 

Actually put pxf in the repository , not in the truststore?

When I check the list of key stores:

 C:\somefolder>keytool -list -keystore "C:\somefolder\clientcert.jks" Enter keystore password: Keystore type: JKS Keystore provider: SUN Your keystore contains 1 entry 67eb31f6, 13-Feb-2013, PrivateKeyEntry, Certificate fingerprint (MD5): ... some fingerprint ... 

So I'm not sure what I am missing here.

+6
source share
2 answers

I found a solution, I should use keyStore, not trustStore, but more importantly, it seems that the problem with the library I am using (cxf 2.7.1), I have to configure the SSL property directly in the code

 // BEGIN FIX to avoid certificate error, need to set this up in the code for cxf String storePath = System.getProperty("javax.net.ssl.keyStore"); String storePassword = System.getProperty("javax.net.ssl.keyStorePassword"); String storeType = System.getProperty("javax.net.ssl.keyStoreType"); KeyStore keyStore = KeyStore.getInstance(storeType); keyStore.load(new FileInputStream(storePath), storePassword.toCharArray()); KeyManagerFactory factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); factory.init(keyStore, storePassword.toCharArray()); KeyManager[] keyManagers = factory.getKeyManagers(); Client client = ClientProxy.getClient(port); HTTPConduit conduit = (HTTPConduit) client.getConduit(); conduit.setTlsClientParameters(new TLSClientParameters()); conduit.getTlsClientParameters().setKeyManagers(keyManagers); 
+3
source

You need to trust the server certificate. Here's how to do it:

Using Chrome (instructions for other users may vary):

  • Arrival at the service site. (example. https://localhost/myService )
  • If the browser does not trust it, click Proceed anyway , click the lock icon in your address bar and do not open the pop-up window, select the Connection tab and the Certificate Information link.
  • This should open the certificate viewer, where, having selected Details , you should see the Export ... button. Select Base 64 encoded, single certificate and save it as mysite.cer .

Receives a certificate, now you need to import it into a trusted store.

Now import the certificate into the keystore:

 keytool -import -file mysite.cer -keystore mykeystore 

This creates a new keystore file in the mykeystore file in the current directory.

Finally, launch the web service client application using the JVM parameter javax.net.ssl.trustStore , as in:

 java -Djavax.net.ssl.trustStore=mykeystore ... MyClientClass 

Or if you use Tomcat on Windows:

 set JAVA_OPTS=-Djavax.net.ssl.trustStore=mykeystore startup.bat 

Or if you use Tomcat on Unix:

 export JAVA_OPTS="-Djavax.net.ssl.trustStore=mykeystore" startup.sh 
+5
source

All Articles