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


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

最佳答案

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

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

how to add subject alernative name to ssl certs?

10-07 17:15