I have set up a tomcat server with SSL running in a vmware on my machine using a self signed certificate. I can connect to this no problem with a browser from my main machine with the url https://myserver:8443.
However, I am not able to connect with a Java client. I always get the below exception. I read that I need to add it as a trusted certificate in the keystore. I went to the site with firefox and saved the certificate as a .cer file, and imported it into the default keystore at c:\users\louis\.keystore. I still have the same problem. I think the problem is the client is not using the keystore, and I don't know how to make it do so. I tried adding the following argument to the run command:
but it doesn't help.
Here is the exception I'm getting:
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
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
... 18 more
Your client's truststore doesn't trust your server's keystore. You have to export the self-signed certificate from the server's keystore and import it into your client's truststore. Believe me it is far simpler to pony up the $50 or whatever it is and get a CA-signed SSL certificate for the server.
Didn't realize it was that cheap, but I still don't really want to do that just for early testing, since that cert won't be used in the final product anyway.
The server is running in a vmware, so it's effectively on a separate machine and has it's own keystore. I created a new keystore for the client, went to the site with a browser and saved the cert to a file, and then imported that to the client's keystore.
I have worked around this problem by configuring the Java client to trust all certificates and disabling hostname verification. That way I don't need a trust store. I'll just have to remove that code in production. Not ideal since I'd rather have certificate/hostname verification working for testing, but it works at least.
I have looked at the Java security documentation and as far as i can tell a keystore and trust store is still basically the same type of file and created the same way with the keytool. The difference is when you import a cert you use the -trustcacerts option. The client 'keystore' is only being used to store the trusted cert, so it essentially is a trust store. This is documented in the keytool doc for the command -importcert.
I actually think my problem is more to do with the hostname, since my server doesn't have a real domain hostname like www.myserver.com. I am just using the machine name for the host, although web browsers do not have a problem with this. When I set my java client to trust all certs, I was getting the following error:
java.io.IOException: HTTPS hostname wrong
Disabling hostname verification fixed this, so I'm wondering if my cert has the wrong hostname. I originally created the self signed cert using the keytool with the command -genkey, which creates a key pair and also a self signed cert. I looked at the keytool docs, and I don't see any way of specifying the hostname or even seeing what the host name of a cert is. What does it put as the hostname by default? The IP address or machine name, or am I understanding this wrong?
Ok this is now solved.
I found out that the common name field of the certificate has to be the hostname. Keytool threw me off because it asked me to put my first and last name for that field.
Also, you were right, I need to specify that it's the truststore, not keystore. I changed the VM arguments to this:
That's a requirement for HTTPS but it doesn't cause the exception you posted above. That exception was resolved by getting the keystore and truststore correct. Hostname verification happens at a later phase and causes a different exception.