连接到具有多个证书的服务器时的java.security.cert.CertificateException

时间:2014-06-05 13:16:59

标签: java ssl certificate wget

我尝试创建与网站(https://www.otten-markenshop.de/)的SSL连接,并使用浏览器或卷曲它可以工作,但是没有wget,没有Java设法连接。我最感兴趣的是为什么Java代码会失败。 以下是错误详细信息:

使用WGET:

wget https://www.otten-markenshop.de/

结果

Resolving www.otten-markenshop.de... 217.24.213.167
Connecting to www.otten-markenshop.de|217.24.213.167|:443... connected.
ERROR: certificate common name “www.plentymarkets.eu” doesn’t match requested 
host name “www.otten-markenshop.de”.

使用Java:

public static void main(String[] args) throws IOException
{
    URL url = new URL("https://www.otten-markenshop.de");
    URLConnection connection = url.openConnection();
    connection.getInputStream();
}

结果:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: 
java.security.cert.CertificateException: No subject alternative DNS 
name matching www.otten-markenshop.de found.

我注意到的是,我在浏览器中收到的证书与运行Java程序时收到的证书不同:

浏览器中的

Common Name (CN): 
    www.otten-markenshop.de
Subject Alternative Name: 
    DNS Name=www.otten-markenshop.de 
    DNS Name=otten-markenshop.de
Java中的

Common Name (CN): 
    www.plentymarkets.eu
Subject Alternative Name: 

如果我尝试通过IP地址访问主机,那么我在Java中获得的证书与在浏览器中获得的证书相同:https://217.24.213.167 因此,服务器似乎安装了多个证书,并使用虚拟主机来检测应使用哪个证书。但由于某些原因,当客户端是Java或wget时,此检测不起作用。

任何想法为什么会发生这种情况?

P.S。我无法访问目标服务器以查看其配置方式。

P.P.S。我更感兴趣的是理解为什么简单的Java代码不起作用,而不是让它工作,例如,禁用SSL验证。毕竟我可以通过HTTP连接到提到的URL而没有任何问题。

1 个答案:

答案 0 :(得分:1)

在同一IP地址和端口上拥有多个证书依赖于服务器名称指示。

您的服务器支持它,但您的客户也需要支持它。

客户端对SNI的支持仅在Java 7中引入Java(参见release notes(*)。我猜您使用的是Java 6或更低版本,否则您使用URLConnection的简单示例应该像这样开箱即用。

(如果您正在使用其他客户端库,例如Apache HTTP Client,则可能还需要其他设置,具体取决于版本。)

(*)这是在Java 8的服务器端引入的,但这不是你的问题。