These may be phrased as separate questions for clarity, but they are all related to the same issue.
How are SSL certificate server names resolved?
Why do browsers seem to use the CN field of the certificate, but Java's mechanism seem to only look at "subject alternative names" only?
Is it possible to add alternative names to a SSL certificate using keytool? If not, is using openSSL instead a good option??
Just a little background: I need to get a main server to communicate with several servers using HTTPS. Obviously, we don't want to buy SSL certificates for every server (there could be many), so I want to use self-signed certificates (I have been using keytool to generate them). After I add the certificates as trusted in the OS, the browsers (IE and Chrome) happily accept the connection as trusted. However, even after adding the certificates to Java's cacerts, Java still won't accept the connection as trusted and throws the following Exception:
Caused by: java.security.cert.CertificateException: No subject alternative names present at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142) at sun.security.util.HostnameChecker.match(HostnameChecker.java:75) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509T rustManagerImpl.java:264) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted( X509TrustManagerImpl.java:250) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien tHandshaker.java:1185) ... 14 more
I found that I can make Java trust the certificate implementing my own HostNameVerifier, which I copied from here: com.sun.jbi.internal.security.https.DefaultHostnameVerifier just to test (by the way, the hostname passed as an argument to the HostnameVerifier is correct, so I think it should have been accepted).
I have been using the certificate field CN as the hostname (usually the IP address).
Can anybody please tell me if I am doing something wrong and point me in the right direction?