为了清楚起见,可以将这些问题表述为单独的问题,但是它们都与同一问题相关。
SSL证书服务器名称如何解析?
为什么浏览器似乎使用证书的CN字段,但是Java的机制似乎仅查看“主题备用名称”?
是否可以使用keytool将替代名称添加到SSL证书?如果不是,使用openSSL代替是一个不错的选择吗?
只是一点点背景:我需要获得一个主服务器,以便使用HTTPS与多个服务器进行通信。显然,我们不想为每台服务器购买SSL证书(可能有很多),所以我想使用自签名证书(我一直在使用keytool生成它们)。在操作系统中将证书添加为受信任的证书后,浏览器(IE和Chrome)欣然接受该连接为受信任的证书。但是,即使将证书添加到Java的cacerts中,Java仍然不会将连接接受为受信任的,并引发以下异常:
由以下原因引起:java.security.cert.CertificateException:sun.security.util.HostnameChecker.match(HostnameChecker.java:75)上的sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142)上没有使用者替代名称。在com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:250)处com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509T rustManagerImpl.java:264) sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien tHandshaker.java:1185)...还有14个
我发现我可以使Java信任实现我自己的HostNameVerifier的证书,该证书是我从此处复制的:com.sun.jbi.internal.security.https.DefaultHostnameVerifier只是为了进行测试(顺便说一下,主机名作为参数传递给了HostnameVerifier是正确的,因此我认为它应该已经被接受)。
我一直使用证书字段CN作为主机名(通常是IP地址)。
有人可以告诉我我做错了什么,并指出正确的方向吗?