我有一台带有自签名证书的服务器。我已经在计算机上使用keytool导入了它并使用
-Djavax.net.ssl.trustStore=blabla
编译参数。当我尝试运行以下代码时:
SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket("MY_URL_DIGITS", 443);
OutputStream os = socket.getOutputStream();
os.write("Test request \n".getBytes());
os.flush();
os.close();
一切顺利,我可以看到"测试请求"在服务器上。但是,当我跑:
URL url = new URL("https://MY_URL_DIGITS");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
OutputStream os = con.getOutputStream();
os.write("Test request \n".getBytes());
os.flush();
os.close();
我有
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
那么这两个片段之间的主要区别是什么?
答案 0 :(得分:1)
区别在于HTTPS添加了一个步骤,可以在HostnameVerifier
界面中看到。它正在尝试将所连接的主机名与SubjectDN
中的主机名或替代名称进行匹配。
答案 1 :(得分:1)
SSLSocket默认只检查您是否信任该证书。 HttpsURLConnection检查您是否信任该证书,并检查证书是否表明它来自您实际导航到的同一个地方。要使HttpsURLConnection成功,证书必须指定与您要连接的服务器相同的主题备用名称(SAN)。在这种情况下,SAN需要是“dns:MY_URL_DIGITS”,其中“dns”部分表示您指定的是主机名而不是IP地址。
如果您需要有关如何使用主题备用名称创建证书的其他信息,请参阅: