i have two https web applications app1 and app2 installed on two different tomcats t1 and t2(t1 and t2 are on different machines). when in app1
i make an url connection to app2 i get the SSL handshake error. The reason is i am using the self signed certificate in app2 which is not present
in app1 jvm truststore. So proper approach to fix it install the self signed certificate in JAVA-HOME/jre/lib/security . To do the
same , I have followed the steps given at http://www.mkyong.com/webservices/jax-ws/suncertpathbuilderexception-unable-to-find-valid-certification-path-to-requested-target/.
Same steps are suggested across the different forums. But still i get the same SSL handshake error which is
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
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
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
My question here is why first approach(which is proper approach) i.e putting the jssecacerts file under /lib/security is not working?
Another point is what is different between first and second approach ?
Best Answer
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 ofC:.keystore
, by the way.)It's probably better to make a copy of your original
cacerts
(orjssecacerts
) 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 ofcacerts
.) Then, configure your JVM running Apache Tomcat (not necessarily the Tomcat connector) to use it. You should be able to set the JVM parameters incatalina.sh
(JAVA_OPTS=-D...
).EDIT:
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 overcacerts
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 ofInstallCert
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 usekeytool -export
to be sure.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 acacerts
file, if you only import your certificate intojssecacerts
,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
orcacerts
: