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