当前位置: 首页 > 面试题库 >

CertificateException:找不到与ssl.someUrl.de匹配的名称

哈涵容
2023-03-14
问题内容

我正在尝试使用Java通过ssl连接到我的一台服务器。我尝试了很多选择,这是我的最佳尝试:

我使用以下推荐脚本生成了jssecacerts:http
:
//blogs.oracle.com/andreas/resource/InstallCert.java,
其中包含以下命令:java InstallCert ssl.someUrl.de changeit

之后,我再次执行了命令:

Loading KeyStore jssecacerts...
Opening connection to ssl.someUrl.de:443...
Starting SSL handshake...

No errors, certificate is already trusted

Server sent 1 certificate(s):

 1 Subject EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   Issuer  EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   sha1    f1 0d 2c 54 05 e1 32 19 a0 52 5e e1 81 6c a3 a5 83 0d dd 67
   md5     f0 b3 be 5e 5f 6e 90 d1 bc 57 7a b2 81 ce 7d 3d

Enter certificate to add to trusted keystore or 'q' to quit: [1]

我将文件复制到默认目录,并将证书加载到Java trustStore中

System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files (x86)\\Java\\jre6\\lib\\security\\jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");

然后我尝试连接

URL url = new URL("https://ssl.someUrl.de/");
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));

我在第三行出现错误:(找不到与ssl.someUrl.de匹配的名称)

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching ssl.someUrl.de found

这是默认的plesk证书的原因还是其他原因?

设置:JRE 6.20,Netbeans 6.8,Windows7 64位


问题答案:

您似乎要连接的服务器的证书与它的主机名不匹配。

HTTPS客户端连接到服务器时,它将验证证书中的主机名是否与服务器的主机名匹配。信任证书还不够,它还必须与您要交谈的服务器匹配。(以此类推,即使您信任一本护照是合法的,您仍然必须检查它是您要与之交谈的人的护照,而不仅仅是您会信任的一本护照。)

在HTTP中,这是通过检查以下内容来完成的:

  • 证书包含与主机名匹配的DNS使用者替代名称(这是标准扩展名)条目;

  • 否则,您的主题专有名称的最后一个CN(如果需要,这是主名称)与主机名匹配。(请参阅RFC2818。)

没有证书就很难说出主题的替代名称(尽管,如果您连接浏览器并更详细地检查其内容,则应该能够看到它。)主题可分辨名称似乎是:

EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Herndon, ST=Virginia, C=US

(因此,如果您还没有使用DNS:ssl.someUrl.de的使用者替代名称,则它应该是CN = ssl.someUrl.de而不是CN =
plesk;我的猜测是您没有。)

您可以使用HttpsURLConnection.setHostnameVerifier(..)绕过主机名验证。编写一个基于验证的自定义HostnameVerifier并不难,尽管我建议仅在证书特别是与此处有关的证书时才这样做。您应该能够使用SSLSession参数及其getPeerCertificates()方法获得该信息。

(此外,由于您仍在使用默认值,因此您无需按照完成操作的方式设置javax.net.ssl。*属性。)

另外,如果您可以控制要连接的服务器及其证书,则可以为其创建一个证书,该证书与上面的命名规则相匹配(CN应该足够,尽管主题备用名称是一个改进)。如果自签名证书足以满足您的名称要求,请确保其公用名(CN)是您要与之交谈的主机名(没有完整的URL,只有主机名)。



 类似资料: