SSLSocketFactory和HttpsURLConnection在哪里不同地工作?

时间:2014-04-21 21:57:10

标签: java ssl ssl-certificate

我有一台带有自签名证书的服务器。我已经在计算机上使用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

那么这两个片段之间的主要区别是什么?

2 个答案:

答案 0 :(得分:1)

区别在于HTTPS添加了一个步骤,可以在HostnameVerifier界面中看到。它正在尝试将所连接的主机名与SubjectDN中的主机名或替代名称进行匹配。

答案 1 :(得分:1)

SSLSocket默认只检查您是否信任该证书。 HttpsURLConnection检查您是否信任该证书,并检查证书是否表明它来自您实际导航到的同一个地方。要使HttpsURLConnection成功,证书必须指定与您要连接的服务器相同的主题备用名称(SAN)。在这种情况下,SAN需要是“dns:MY_URL_DIGITS”,其中“dns”部分表示您指定的是主机名而不是IP地址。

如果您需要有关如何使用主题备用名称创建证书的其他信息,请参阅:

how to add subject alernative name to ssl certs?