Though it i got rid of this SSLHandshakeException by mentioning below
parameters in JVM trustore. -Djavax.net.ssl.trustStore=C:.keystore
-Djavax.net.ssl.trustStorePassword=changeit
It's not clear what you were trying to do with these options. Either you use the default truststore (normally jssecacerts
, if it exists; otherwise, cacerts
) or you specify your own. .keystore
tends to be used as a keystore, not truststore (although there is no default JSSE value). (I would also specify the full path instead of C:.keystore
, by the way.)
It's probably better to make a copy of your original cacerts
(or jssecacerts
) file (remove the extra one you've put, if you've changed something) and add your remote certificate to it (i.e. app2's cert in app1's copy and app1's cert in app2's copy, if needed).
You can list the certificates using keytool -list -keystore keystore.jks
(see help for more options if needed).
You can export a certificate using keytool -export -keystore server1-keystore.jks -alias server_alias -file server1.crt
.
Then, import it in the other truststore: keytool -import -keystore client2-truststore.jks -file server1.crt
. (Here, client2-truststore.jks
will be a copy of cacerts
.)
Then, configure your JVM running Apache Tomcat (not necessarily the Tomcat connector) to use it. You should be able to set the JVM parameters in catalina.sh
(JAVA_OPTS=-D...
).
EDIT:
My question here is why first approach(which is proper approach) i.e
putting the jssecacerts file under /lib/security is not working?
To answer your question more directly, I've just double-checked on a clean Oracle JRE 6 installation (1.6.0_31), and jssecacerts
takes precedence over cacerts
when present (as documented in the JSSE Ref Guide, so there doesn't seem to be a bug). I'm not sure where Oracle have moved Andreas Sterbenz's Sun blog, so I'm not sure which copy of InstallCert
you've used. I guess something my have gone wrong there.
As far as I'm aware, InstallCert
connects to the server to get its certificate (replacing the export step above): you effectively assume that the certificate you get on your first connection is the right one (and can be trusted). You could also get that certificate using OpenSSL. However, in your case, you seem to have control over the two servers and their respective keystores, so you might as well use keytool -export
to be sure.
Another point is what is different between first and second approach ?
The first approach (changing jssecacerts
) sets the configuration for all applications that will use this installation of the JRE, whereas the second will apply those settings to the JVM once it's running Apache Tomcat only.
Note, that if you didn't have a jssecacerts
but only a cacerts
file, if you only import your certificate into jssecacerts
, cacerts
will be ignored, so you won't be able to connect to servers that have a certificate issued by a CA that would normally be trusted by default. That's why starting with a copy of the default file can be useful. (In addition, if your application also connects to other sites that would normally be trusted by default, this could also explain why you'd get this error message, at a different place this time.)
Ultimately, it's your responsiblity to check what's in jssecacerts
or cacerts
:
IMPORTANT NOTE: The JDK ships with a limited number of trusted root
certificates in the /lib/security/cacerts file. As documented in
keytool, it is your responsibility to maintain (that is, add/remove)
the certificates contained in this file if you use this file as a
truststore.
Depending on the certificate configuration of the servers you contact,
you may need to add additional root certificate(s). Obtain the needed
specific root certificate(s) from the appropriate vendor.